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 ソケットを待機し、それが受け入れられると、再帰して async が別のソケットを待機します。

await セクションによってコードが呼び出し元に返されるため、スタック オーバーフローが発生しないため、これは問題なく機能するようです。

ここで2つの質問:

  1. このサンプルでソケットを扱っているという事実を無視すると。この方法でスタックフリー再帰を実行しても問題ありませんか? または、欠けている欠点はありますか?

  2. IO の観点から、上記のコードはすべての着信要求を処理するのに十分でしょうか? つまり、1つを待つだけで、それが受け入れられたら、別の1つを待ち始めます。これが原因で一部のリクエストが失敗することはありますか?

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 に答える