等待套接字操作 [英] Awaiting Socket Operations

查看:63
本文介绍了等待套接字操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下代码,这些代码是从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆