Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
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 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
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 continuation it works like I expected
int c = counter;
TaskEx.Delay(5000, cts.Token).ContinueWith(t => {
Console.WriteLine("Response " + c);
// send response
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 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.
–
–
I figured out how to accomplish what I wanted to do (i.e. use await
instead of .ContinueWith
and delegates):
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);
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.