如何异步等待连接?
How to wait for a connection asynchronously?
我设计了一个 class,它包装了一个 Socket
并允许发送和接收 through/from。由于接受、发送和接收是通过 UI 完成的,我不希望他们阻止它,因此我使用了他们的异步版本。
相关代码如下:
public void Accept()
{
// ...
// where resultAccept is a IAsyncResult
resultAccept = listener.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
private void AcceptCallback(IAsyncResult ar)
{
connectedSocket = listener.EndAccept(ar);
}
public string Receive()
{
char[] data = new char[128];
if (!resultAccept.IsCompleted) // (1)
resultAccept.AsyncWaitHandle.WaitOne();
connectedSocket.BeginReceive(Encoding.UTF8.GetBytes(data), 0, data.Length, SocketFlags.None,
new AsyncCallback(RecvCallback), null);
// ...
}
当我开始接收时,由于还没有连接,它必须等待一 (1) 次并阻止 UI(同样,我不想要)。
此外,当连接被接受时,我得到一个 NullReferenceException
因为当 BeginReceive
开始时, AcceptCallback
是,是触发,但尚未完成,所以 connectedSocket
仍然必须已初始化。
- 为什么我的方法不对?
- 是否可以使用异步套接字实现我想要的?
- 如何防止UI在等待连接时阻塞并确保对象的有效性?
- 是的,因为你在阻止。你需要把它扔掉。
- 是的,Web 上有
Socket
扩展方法将过时的 APM 模式适配为 TAP 模式,以便您可以使用 await。这样练习就变得微不足道了。
您的代码应如下所示:
async Task RunServer() {
Socket serverSocket = ...;
while (true) {
RunConnection(await serverSocket.AcceptAsync());
}
}
然后提供一个 Task RunConnectionAsync(Socket s)
异步函数。一旦您不理会过时的 APM 模式,真的很简单。
或者,只使用线程和同步 IO。这样做没有错。 await
稍微好一点,因为它会自动为您编组回 UI 线程。
我设计了一个 class,它包装了一个 Socket
并允许发送和接收 through/from。由于接受、发送和接收是通过 UI 完成的,我不希望他们阻止它,因此我使用了他们的异步版本。
相关代码如下:
public void Accept()
{
// ...
// where resultAccept is a IAsyncResult
resultAccept = listener.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
private void AcceptCallback(IAsyncResult ar)
{
connectedSocket = listener.EndAccept(ar);
}
public string Receive()
{
char[] data = new char[128];
if (!resultAccept.IsCompleted) // (1)
resultAccept.AsyncWaitHandle.WaitOne();
connectedSocket.BeginReceive(Encoding.UTF8.GetBytes(data), 0, data.Length, SocketFlags.None,
new AsyncCallback(RecvCallback), null);
// ...
}
当我开始接收时,由于还没有连接,它必须等待一 (1) 次并阻止 UI(同样,我不想要)。
此外,当连接被接受时,我得到一个 NullReferenceException
因为当 BeginReceive
开始时, AcceptCallback
是,是触发,但尚未完成,所以 connectedSocket
仍然必须已初始化。
- 为什么我的方法不对?
- 是否可以使用异步套接字实现我想要的?
- 如何防止UI在等待连接时阻塞并确保对象的有效性?
- 是的,因为你在阻止。你需要把它扔掉。
- 是的,Web 上有
Socket
扩展方法将过时的 APM 模式适配为 TAP 模式,以便您可以使用 await。这样练习就变得微不足道了。
您的代码应如下所示:
async Task RunServer() {
Socket serverSocket = ...;
while (true) {
RunConnection(await serverSocket.AcceptAsync());
}
}
然后提供一个 Task RunConnectionAsync(Socket s)
异步函数。一旦您不理会过时的 APM 模式,真的很简单。
或者,只使用线程和同步 IO。这样做没有错。 await
稍微好一点,因为它会自动为您编组回 UI 线程。