如果线程仍在等待,异步连接的目的是什么?



我遇到了以下代码:

public ManualResetEvent allDone = new ManualResetEvent(false);
public void connectCallback(IAsyncResult ar)
{
allDone.Set();
Socket s = (Socket)ar.AsyncState;
s.EndConnect(ar);
}
public int connect()
{
try
{
var address = Dns.GetHostEntry(host).AddressList[0];
var remoteEP = new IPEndPoint(address, port);
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.BeginConnect(remoteEP, new AsyncCallback(connectCallback), socket);
allDone.WaitOne(15000);
return true;
}
catch (Exception)
{
return false;
}  
}

看起来它使用回调方法调用BeginConnect。 然后,代码等待 ManualResetEvent 触发,该事件在回调方法中设置。

同步连接不是更简单吗,因为代码无论如何都在等待(15 秒超时不变(:

public int connect()
{
try
{
var address = Dns.GetHostEntry(host).AddressList[0];
var remoteEP = new IPEndPoint(address, port);
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(remoteEP);
return true;
}
catch (Exception)
{
return false;
}  
}

在这种情况下,是的,您在技术上是正确的。像这样的模式习惯于潜入代码库,通常是因为我们希望利用异步模式作为标准方法,但有时我们会遇到冲突的现有同步布尔响应代码协定。

但是,异步回调模式仍然有效,因为您已将回调处理限制为可以从多个连接进程中重用的单个函数,我们看不到类结构的其余部分,但此模式很容易允许存在多个重载Connect。也许Connect已经有一个完全异步的过载......

由于这是同步异步范式之间的明确连接,因此我鼓励开发人员添加注释,详细说明等待发生的原因,以及为什么将来应该或不应该重构它。

是的,异步 (APM( 调用和 ManualResetEvent 或多或少地相互抵消。

确保您了解 TaskFactory.FromAsync 方法,以使其成为基于任务的异步连接方法。

最新更新