Вопрос по sockets, c# – Безопасна ли асинхронная рекурсия в C # (async ctp / .net 4.5)?

21

В C # с async ctp или бета-версией vs.net 2011 мы можем написать рекурсивный код, подобный этому:

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 возвращает код вызывающей стороне и, следовательно, не вызывает переполнения стека.

Итак, два вопроса здесь:

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?

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?

По сути, я не вижу в этом ничего плохого, но что это добавляет к IMO более просто?public async void AwaitSocket() { while (true) { var socket = await this.AcceptSocketAsync(); Handle(socket); } }? user743382
Так когда жеHandle(socket) когда-нибудь бегал? leppie
@RogerAlsing Ты уверен в этом?await может завершиться синхронно, и в этом случае порядок будет испорчен. user743382
@RogerAlsing Нет,await doesn't всегда возвращайтесь напрямую, как я уже упоминал в предыдущем комментарии. Этоmay возвратите напрямую, или, если результат уже доступен без ожидания, он может обработать результат напрямую. user743382
@hvd: Этот материал только ранит мой мозг! ;п leppie

Ваш Ответ

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...
}
Error: User Rate Limit Exceeded Roger Johansson
Error: User Rate Limit Exceededasync voidError: User Rate Limit ExceededasyncError: User Rate Limit ExceededTask/Task<TResult>Error: User Rate Limit ExceededmustError: User Rate Limit ExceededvoidError: User Rate Limit Exceededasync voidError: User Rate Limit ExceededallowedError: User Rate Limit Exceededrecommended.
Error: User Rate Limit ExceededAcceptSocketAsync()Error: User Rate Limit ExceededHandleAsync()Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededTcpListener.StartError: User Rate Limit ExceededbacklogError: User Rate Limit ExceededbacklogError: User Rate Limit Exceededon your behalfError: User Rate Limit Exceededblog postError: User Rate Limit Exceeded
Error: User Rate Limit ExceededYieldError: User Rate Limit ExceededAcceptSocketAsyncError: User Rate Limit ExceededHandleAsyncError: User Rate Limit ExceededawaitError: User Rate Limit Exceeded

Похожие вопросы