21

在带有 async ctp 或 vs.net 2011 beta 的 C# 中,我们可以编写如下递归代码:

public async void AwaitSocket()
{
    var socket = await this.AcceptSocketAsync(); //await socket and >>return<< to caller
    AwaitSocket(); //recurse, note that the stack will never be deeper than 1 step since await returns..
    Handle(socket); // this will get called since "await" returns
}

在这个特定的示例中,代码 async 等待一个 tcp 套接字,一旦它被接受,它将递归并异步等待另一个。

这似乎工作正常,因为等待部分将使代码返回给调用者,因此不会导致堆栈溢出。

所以这里有两个问题:

  1. 如果我们忽略这个示例中我们正在处理套接字的事实。以这种方式进行无堆栈递归可以吗?还是我缺少缺点?

  2. 从 IO 的角度来看,上面的代码是否足以处理所有传入的请求?我的意思是只等待一个,一旦被接受就开始等待另一个。某些请求会因此而失败吗?

4

1 回答 1

2

从上面的讨论中,我想这样的方法将是最好的方法。请反馈

public async void StartAcceptingSockets()
{
    await Task.Yield(); 
    // return to caller so caller can start up other processes/agents
    // TaskEx.Yield in async ctp , Task.Yield in .net 4.5 beta

    while(true)
    {
        var socket = await this.AcceptSocketAsync();
        HandleAsync(socket); 
        //make handle call await Task.Yield to ensure the next socket is accepted as fast 
        //as possible and dont wait for the first socket to be completely handled
    } 
}

private async void HandleAsync(Socket socket)
{
      await Task.Yield(); // return to caller

      ... consume the socket here...
}
于 2012-05-30T11:08:07.693 回答