c# - 如果线程仍在等待,异步连接的目的是什么?
问题描述
我遇到了以下代码:
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
......
由于这是同步和异步范式之间的明确结合,我鼓励开发人员包含详细说明等待发生的原因以及将来应该或不应该重构它的原因的注释。
推荐阅读
- java - 我可以将我的 SQLite 数据库存储在任何云存储/在线数据库中吗?
- javascript - “X”未定义 - 在 Javascript 中使用“For 循环”
- html - 使用浮动对齐徽标时,标头会出现不稳定的 HTML
- codeigniter - Codeigniter 4 hasChanged() - 我期待没有变化,但 hasChanged() 返回 true,它已经改变
- python - 如何控制 QFrame 在布局中的比例?
- python - 我在谷歌识别中遇到查找错误
- centos - centos 7 无法安装并出现错误:未知芯片组?
- graphql - 没有输入参数的 Graphql 突变不起作用
- android - 在 Flutter 的 PageView.builder 中插入自定义页面
- html - 使整个单词转到下一行,而不是将它们分成两半