如何为异步等待调用创建包装器?
据我所知,没有对 ConnectAsync/AcceptAsync/SendAsync/ReceiveAsync 的内置(或框架扩展)支持 等。我将如何编写自己的包装器,该包装器将受到异步等待机制的支持。例如,我当前的代码处理内联和回调上的 ReceiveAsync(在 SocketAsyncEventArgs 中指定):
private void PostReceive(SocketAsyncEventArgs e)
{
e.SetBuffer(ReceiveBuffer.DataBuffer, ReceiveBuffer.Count, ReceiveBuffer.Remaining);
e.Completed += Receive_Completed;
// if ReceiveAsync returns false, then completion happened inline
if (m_RemoteSocket.ReceiveAsync(e) == false)
{
Receive_Completed(this, e);
}
}
。
private void Receive_Completed(object sender, SocketAsyncEventArgs e)
{
e.Completed -= Receive_Completed;
if (e.BytesTransferred == 0 || e.SocketError != SocketError.Success)
{
if (e.BytesTransferred > 0)
{
OnDataReceived(e);
}
Disconnect(e);
return;
}
OnDataReceived(e);
//
// we do not push the SocketAsyncEventArgs back onto the pool, instead
// we reuse it in the next receive call
//
PostReceive(e);
}
From what I can tell, there is no built-in (or framework extension) support for ConnectAsync
/AcceptAsync
/SendAsync
/ReceiveAsync
, etc.. How would I write my own wrapper that would be supported by the async-await mechanism. For example, my current code which handles a ReceiveAsyn
c both inline and on the callback (which is specified in the SocketAsyncEventArgs
):
private void PostReceive(SocketAsyncEventArgs e)
{
e.SetBuffer(ReceiveBuffer.DataBuffer, ReceiveBuffer.Count, ReceiveBuffer.Remaining);
e.Completed += Receive_Completed;
// if ReceiveAsync returns false, then completion happened inline
if (m_RemoteSocket.ReceiveAsync(e) == false)
{
Receive_Completed(this, e);
}
}
.
private void Receive_Completed(object sender, SocketAsyncEventArgs e)
{
e.Completed -= Receive_Completed;
if (e.BytesTransferred == 0 || e.SocketError != SocketError.Success)
{
if (e.BytesTransferred > 0)
{
OnDataReceived(e);
}
Disconnect(e);
return;
}
OnDataReceived(e);
//
// we do not push the SocketAsyncEventArgs back onto the pool, instead
// we reuse it in the next receive call
//
PostReceive(e);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
诀窍是使用 TaskCompletionSource 来处理这种情况。
我在博客上谈到了这一点。有关详细信息,请参阅 为 Await 准备现有代码。
The trick is to use TaskCompletionSource to handle this scenario.
I blogged about this. For details, see Preparing Existing code For Await.
您还可以编写一个自定义等待,在这种情况下我更喜欢它。这是 Microsoft 的 Stephen Toub 提出的一项技术。您可以在此处阅读有关此技术的更多信息。
http://blogs.msdn.com/b/pfxteam /archive/2011/12/15/10248293.aspx
这是自定义的可等待:
添加到套接字类并使其方便的一些扩展方法:
在使用中:
You can also write a custom awaitable, which I like better in this situation. This is a technique by Stephen Toub from Microsoft. You can read more about this technique here.
http://blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx
Here is the custom awaitable:
Some extension methods to add to the socket class and make it convenient:
In use:
对于套接字内容,.NET 4.5 中有一个包装器。如果您使用 .NET 4,我建议您使用 APM,而不是基于事件的异步模式。它更容易转换为
Task
。For socket stuff there is a wrapper in .NET 4.5. If you are on .NET 4 I'd recommend to use the APM and not the event-based asynchronous pattern. It converts to
Task
's far more easily.