等待TaskEx.Delay

我正在玩HttpListener和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个客户端同时连接时,我期望以下输出

 Client connected 1 Client connected 2 Client connected 3  Response 1 Response 2 Response 3 

相反,我得到了

 Client connected 1  Response 1 Client connected 2  Response 2 Client connected 3  Response 3 

如果我使用延续,它就像我预期的那样工作

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

我的印象是await TaskEx.Delay立即返回(并将转到while (!cts.IsCancellationRequested) )并且while块的其余部分将是5000ms之后的延续。 所以它应该与我的代码相同.ContinueWith ,不是吗?

TaskEx.Delay将立即返回一个任务,但是在再次调用listener.GetContextAsyncTask()之前,您正在等待该任务。 一旦你点击第一个尚未完成的await语句, 调用者Start )将继续,但 Listen方法中,它具有同步代码的外观 – 这就是await

词法的其余部分不是在连续出现时发生的词汇 – 它是“方法执行的剩余部分”。 换句话说,该方法在await有效地“暂停”,但允许调用者继续。

我想出了如何完成我想要做的事情(即使用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); }