CCR
你可能要问,第三方的开发者都提供了这些改进异步编程的类库,难道微软就没有么?
微软的CCR(Concurrency and Coordination Runtime)是为机器人开发平台中需要并行协作而开发的类库。下面我会先简单介绍一下CCR对并发编程的支持,然后介绍一下其对异步编程模型的简化。
在CCR中有一个核心类型Dispatcher,每个Dispatcher都管理着一些线程,相当于一个线程池。与CLR的ThreadPool不同的是,每个Dispatcher都对应着一个自己的“线程池”,而每个CLR中只有一个ThreadPool。一般会将一个Dispatcher与一个DispatcherQueue绑定,任务会进入DispatcherQueue这个队列,然后Dispatcher管理的线程就会执行这个队列里的任务。从这一点看很像我们在上一篇已经接触过的IO完成端口的行为。
CCR中对并发的实现应该算actor-based模型,熟悉Erlang的同学应该会很清楚这个东西。在CCR中,我们创建一个Port
{
//创建一个任务队列与一个Dispatcher绑定
DispatcherQueue taskQueue = new DispatcherQueue("task queue",dispatcher);
Port sender = new Port();
//创建一个接受者,监视sender
Receiver receiver = Arbiter.Receive(true, sender,delegate(String message) { Console.WriteLine(message);})
//该接受者接收到消息后会向taskQueue推入一个任务
Arbiter.Active(taskQueue,receiver);
//发送消息
sender.Post("Hello");
}
上面是使用CCR进行message-based并发编程,message-based的并发编程的好处是避免了Shared Memory,也就不需要锁机制了,简化了并发编程的模型。
而CCR中还提供了FromIteratorHandler这么一个方法,其接受一个IEnumerable参数,表示IEnumerable里每一项都是都是一个操作。有了这个我们再和“神奇的yield”结合起来,又可以大大简化异步开发了:
2: {
3: var resultPort = new Port();
4:
5: var request = WebRequest.Create("http://www.google.com");
6: request.BeginGetResponse(resultPort.Post,null);
7:
8: yield return resultPort.Receive();
9:
10: var response = request.EndGetResponse((IAsyncResult)resultPort.Test());
11:
12: using(var stream = response.GetResponseStream())
13: {
14: var buffer = new byte[1024];
15:
16: stream.BeginRead(buffer,0,1024,resultPort.Post,null);
17:
18: yield return resultPort.Receive();
19:
20: var actualRead = stream.EndRead((IAsyncResult)resultPort.Test());
21:
22: Console.WriteLine(Encoding.Default.GetString(buffer,0,actualRead));
23: }
24: }
然后使用下面的代码运行:
2: DispatcherQueue queue = new DispatcherQueue("download", dispatcher);
3: Arbiter.Activate(queue, Arbiter.FromIteratorHandler(Download));
关于CCR更详细的资料参见这里。Jeffrey Ritcher也在MSDN杂志上有一篇文章介绍CCR,该文的示例代码中还有对各种异步IO的封装代码。