等待TaskEx.Delay [英] await TaskEx.Delay

查看:138
本文介绍了等待TaskEx.Delay的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我摆弄的HttpListener和异步CTP

I am playing 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();
    }
}

我的预期以下输出3时在客户端同时连接

I expected 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

相反,我得到

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

如果我继续使用它就像我的预期。

If I use continuation it works like I expected

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

我是IM pression下的等待TaskEx.Delay 立即返回(并会去而(!cts.IsCancellationRequested) )和该块,而其余将是5000毫秒后的延续。所以应该是一样的我的code与 .ContinueWith ,不是吗?

I was under the impression that await TaskEx.Delay returns immediately (and will go to while (!cts.IsCancellationRequested)) and the remainder of the while block will be the continuation after 5000ms. So it should be the same as my code with .ContinueWith, no?

推荐答案

TaskEx.Delay会立即返回一个任务,但你的等待的这个任务你打电话之前监听器.GetContextAsyncTask()一次。在主叫的(开始)将尽快你打的第一个的await 语句继续它是不是已经完成了,但是的 的内部收听方法,它具有同步code的外观 - 这是点< <$ C $的C / EM>>等待。

TaskEx.Delay will return a task immediately, but you're awaiting that task before you call listener.GetContextAsyncTask() again. The caller (Start) will continue as soon as you hit the first await statement which isn't already completed, but within the Listen method, it has the appearance of synchronous code - that's the point of await.

它不是的块的余数词汇,当继续火灾发生 - 它是的方法的执行的余数。换句话说,该方法有效地暂停的等待,但允许的主叫的继续。

It's not "the remainder of the block" lexically that occurs when the continuation fires - it's "the remainder of the execution of the method". In other words, the method effectively "pauses" at the await, but allows the caller to proceed.

这篇关于等待TaskEx.Delay的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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