Wait for TaskEx.Delay

I play with HttpListener and Async CTP

class HttpServer : IDisposable
{
    HttpListener listener;
    CancellationTokenSource cts;

    public void Start()
    {
        listener = new HttpListener();
        listener.Prefixes.Add("http://+:1288/test/");
        listener.Start();

        cts = new CancellationTokenSource();

        Listen();
    }

    public void Stop()
    {
        cts.Cancel();
    }

    int counter = 0;

    private async void Listen()
    {
        while (!cts.IsCancellationRequested)
        {
            HttpListenerContext context = await listener.GetContextAsyncTask(); // my extension method with TaskCompletionSource and BeginGetContext
            Console.WriteLine("Client connected " + ++counter);

            // simulate long network i/o
            await TaskEx.Delay(5000, cts.Token);

            Console.WriteLine("Response " + counter);
            // send response
        }

        listener.Close();
    }
}

I was expecting the following output when 3 clients connect at the same time

Client connected 1
Client connected 2
Client connected 3
<5000ms pause>
Response 1
Response 2
Response 3

Instead i get

Client connected 1
<5000ms pause>
Response 1
Client connected 2
<5000ms pause>
Response 2
Client connected 3
<5000ms pause>
Response 3

If I use the sequel, it works as I expected

int c = counter;
TaskEx.Delay(5000, cts.Token).ContinueWith(t => {
    Console.WriteLine("Response " + c);
    // send response
});

I had the impression that it await TaskEx.Delaywould immediately return (and go to while (!cts.IsCancellationRequested)), and the remainder of the while block would continue after 5000 ms. So it should be the same as my code with .ContinueWith, no?

+3
source share
2 answers

TaskEx.Delay , , listener.GetContextAsyncTask(). (Start) , await, , Listen - await.

" ", , - " ". , "" await, .

+5

, , (.. await .ContinueWith ):

private async void Listen()
{
    while (!cts.IsCancellationRequested)
    {
        HttpListenerContext context = await listener.GetContextAsyncTask();
        Console.WriteLine("Client connected " + ++counter);

        ProcessRequest(context, counter);
    }

    listener.Close();
}

private async void ProcessRequest(HttpListenerContext context, int c)
{
    await TaskEx.Delay(5000, cts.Token);
    Console.WriteLine("Response " + c);
}
+1

Source: https://habr.com/ru/post/1626208/


All Articles