SOCKET Communication writen in C# (5) Socket 异步操作 模式
异步调用CallBack的示例
http://msdn.microsoft.com/zh-cn/library/5zwkzwf4.aspx
以Socket..::.BeginSend
Socket EndSend
方法为例子来说明
1.调用 BeginSend 的方法将使您能够在单独的执行线程中发送数据。
2.state 参数,则可以创建一个小型类或结构,用于保存 Socket 和其他所需的信息。通过 state 参数将此类的一个实例传递给 BeginSend 方法。
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
3.系统将使用一个单独的线程来执行指定的回调方法,并阻止 EndSend,直到 Socket 发送了请求的字节数或引发了异常为止
4.异步操作的一种模式,分两种情况.
往往我在调用完BeginSend方法之后,方法立即返回,则当前执行线程可以做一些其它的事情,但是如果调用BeginSend后要使当前线程暂停等待,则一般使用WaitHandle..::.WaitOne 方法.
当需要它继续执行时候调用 T:System.Threading.ManualResetEvent 的 Set 方法
使用异步操作自己的同步机制:
a.可以通过调用 result.AsyncWaitHandle.WaitOne(); 方法进行等待异步操作完成。
b.经过测试,当异步调用完成后比如BeginSend,会自动发出 WaitHandle 信号,不需要手动发送,同时这也和EndInoke无关,我将EndInvoke注释掉,一样自动发出了WaitHandle信号; 具体可以去看看
http://msdn.microsoft.com/zh-cn/library/system.iasyncresult.aspx 代码
使用手动同步对象ManualResetEvent
a) System.Threading.ManualResetEvent ManualSign = new System.Threading.ManualResetEvent(false);
b) 在需要等待的地方curr.ManualSign.WaitOne();
c) 异步完成或回调中手动发送信号this.ManualSign.Set();
则完成
5.可以看到实际上,在某些情况下你可以不用调用EndInvoke方法,除非你需要获得返回内容或了解其异步操作的状态或者想要阻塞当前线程直到异步完成或是发生异常,保证正确完成了异步处理.
后面将说明 异步操作的原理和自己实现线程池的方式