我们知道yield return可以用来生成迭代器,它的原理是将函数的调用堆栈保存起来,并在下一次调用迭代器的MoveNext()方法时恢复堆栈以继续运行.
那么我们在调用一个对象上的阻塞io操作时,可以通过yield return来保存调用堆栈,当阻塞io操作可以继续时,就恢复堆栈继续运行.下面用一个例子来说明假设写一个回显服务器用多线程实现如下
    }


在这里我们使了一个独立的线程来处理来自客户端的连接.每一个客户端连接就需要一个线程.
下面我们来用yield来实现它,客户端连接处理函数改成下面的形式
使用yield编写并行程序
使用yield编写并行程序        IEnumerator
<Request> OnClient(Socket socket)
        }


IO请求对象的定义如下
使用yield编写并行程序        class Request
        }

上面用到的创建函数定义如下
使用yield编写并行程序        Request CreateRequest(Socket socket, SelectMode mode)
        }


和上面的多线程版本对比一下,可以发现在socket.Receive()和socket.Send()前面多了一个yield return其它没有区别.下面我们来实现io请求的检测和运行调度,添加一个全局的运行堆栈队列和一个全局的io请求队列

();



调度函数实现如下
使用yield编写并行程序
        }


这样就完整的实现了一个模拟多线程的回显服务了,它有以下几个特点
1.是单线程的,但具有与多线程版本一样的功能,支持同时处理多个客户端连接
2.客户端处理逻辑象多线程版本一样简单,不象异步io那样需要写一个复杂的状态机

下面是完整的源代码
使用yield编写并行程序using System;
使用yield编写并行程序
using System.Collections.Generic;
使用yield编写并行程序
using System.Text;
使用yield编写并行程序
using System.Net;
使用yield编写并行程序
using System.Net.Sockets;
使用yield编写并行程序
使用yield编写并行程序
namespace Networks

相关文章: