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.