是异步递归在C#(异步CTP / .NET 4.5)安全吗? [英] Is async recursion safe in C# (async ctp/.net 4.5)?

查看:811
本文介绍了是异步递归在C#(异步CTP / .NET 4.5)安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中使用异步CTP或vs.net 2011测试版,我们可以编写递归code是这样的:

 公共异步无效AwaitSocket()
{
    VAR插座=等待this.AcceptSocketAsync(); //等待插座和大于;>返回<<呼叫者
    AwaitSocket(); //递归,请注意,堆栈决不会更深大于1的步骤,因为等待返回..
    手柄(插座); //这将调用,因为等待的回报
}

在这个特定的示例中,code异步等待一个TCP套接字一旦被接受,它会重复并异步等待一个又一个。

这似乎很好地工作,因为部分的await将使code返回给调用者,因此,不会导致堆栈溢出。

于是两个问题在这里:


  1. 如果我们忽略我们正在处理此示例中插座的事实。
    它是确定做堆叠免费递归这种方式?还是有弊端林失踪?


  2. 从IO的角度来看,将上述code就足以处理所有传入的请求?
    我的意思只是在等待一个,一旦被接受开始等待另一个。
    将一些请求,因为这个失败不知何故?



解决方案

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

 公共异步无效StartAcceptingSockets()
{
    等待Task.Yield();
    //返回到调用程序,以便调用者可以启动其他程序/代理商
    // TaskEx.Yield在异步CTP,Task.Yield在.NET 4.5测试版    而(真)
    {
        VAR插座=等待this.AcceptSocketAsync();
        HandleAsync(插座);
        //使处理呼叫等待Task.Yield以确保下一个套接字被接受为快
        //尽可能并且不要等待第一个插座被完全处理
    }
}私人异步无效HandleAsync(Socket套接字)
{
      等待Task.Yield(); //返回到调用者      ...这里消费插槽...
}

In C# with async ctp or the vs.net 2011 beta we can write recursive code like this:

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
}

In this specific sample, the code async waits for a tcp socket and once it has been accepted, it will recurse and async wait for another one.

This seems to work fine, since the await section will make the code return to the caller and thus, not cause a stack overflow.

So two questions here:

  1. if we ignore the fact we are dealing with sockets in this sample. Is it OK to do stack free recursion this way? or are there drawbacks Im missing?

  2. from an IO perspective, would the above code be enough to handle all incoming requests? I mean by just waiting for one, and once it is accepted start waiting for another one. Will some requests fail because of this somehow?

解决方案

From the discussion above, I guess something like this will be the best approach. Please give feedback

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...
}

这篇关于是异步递归在C#(异步CTP / .NET 4.5)安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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