等待套接字操作 [英] Awaiting Socket Operations
问题描述
给出以下代码,这些代码是从Stephen Toub的文章中修改而来的. http://blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx
Given the following code, modified from Stephen Toub's article. http://blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx
public async Task Start(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
await this.acceptCount.WaitAsync(token).ConfigureAwait(false);
if (token.IsCancellationRequested)
break;
var args = new SocketAsyncEventArgs();
args.UserToken = new SocketFrame
{
CancellationToken = token,
Buffer = null,
Message = null,
};
// How do I manage this additional task?
args.Completed += (s, e) => this.AcceptInbound((Socket)s, e).Wait(token);
if (!this.socket.AcceptAsync(args))
await this.AcceptInbound(this.socket, args);
}
}
private async Task AcceptInbound(Socket sender, SocketAsyncEventArgs e)
{
var frame = (SocketFrame)e.UserToken;
this.acceptCount.Release();
Socket connectedClient = e.AcceptSocket;
var args = new SocketAsyncEventArgs();
args.SetBuffer(new byte[0x1000], 0, 0x1000);
var awaitable = new SocketAwaitable(args);
while (!frame.CancellationToken.IsCancellationRequested)
{
await connectedClient.ReceiveAsync(awaitable);
var bytesRead = args.BytesTransferred;
if (bytesRead <= 0)
break;
if (this.AppendByteArrayToFrame(frame, args.Buffer, bytesRead))
this.reader.MessageReceived(frame.Message);
}
}
如何避免在 args.Completed
事件上使用 Wait
?我希望在AcceptInbound中引发的异常冒出来,所以我真的不想在那等.
How do I avoid the Wait
on the args.Completed
event?
I want exceptions raised in AcceptInbound to bubble up, so I really don't want to wait there.
我要实现的目的是将AcceptInbound任务绑定到当前任务,以便当我等待当前任务时,捕获引发的异常.
What I am trying to achieve is to bind the AcceptInbound task to the current task, so that when I wait on the current task, the exceptions raised are caught.
推荐答案
您可以注册 async
事件处理程序(这是唯一的 async void
位置).这样您就可以 await
而不是通过 Wait
进行阻止:
You can register an async
event handler (which is the only place async void
is appropriate). That allows you to await
instead of blocking with Wait
:
args.Completed += async (s, e) => await AcceptInbound((Socket)s, e);
如果相反,您希望 Start
处理所有这些任务的完成和异常,那么我将全部存储它们,直到 Start
完成,然后使用 Task.WhenAll
,以确保所有操作均已完成,并抛出它们可能产生的任何异常:
If instead you want Start
to handle completion and exceptions from all these tasks then I would store them all until Start
completes and then use Task.WhenAll
to make sure all operations completed and rethrow any exception they may produced:
public async Task Start(CancellationToken token)
{
var tasks = new ConcurrentBag<Task>();
while (!token.IsCancellationRequested)
{
// ...
args.Completed += (s, e) => tasks.Add(AcceptInbound((Socket)s, e));
// ...
}
await Task.WhenAll(tasks);
}
这篇关于等待套接字操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!