首页 > 解决方案 > 如果线程仍在等待,异步连接的目的是什么?

问题描述

我遇到了以下代码:

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;
  }  
}

标签: c#.net.net-core

解决方案


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

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

由于这是同步异步范式之间的明确结合,我鼓励开发人员包含详细说明等待发生的原因以及将来应该或不应该重构它的原因的注释。


推荐阅读