Here's a significantly reduced test case from a piece of code I'm working on:
var i = 0;
var taskCompletionSource = new TaskCompletionSource<object>();
var task = taskCompletionSource.Task;
Task.Run(async () =>
{
await task;
i = 1;
});
// Synchronously complete `task`
taskCompletionSource.SetResult(null);
// ???
Console.WriteLine(i);
Assuming that this code runs in the context of an async
method, what should replace // ???
to ensure that this code prints 1
rather than 0
?
I believe I understand why as written the program will always print 0
-- the code is executing synchronously and nothing has yielded to the scheduler. But I am surprised to learn that
await Task.Yield();
doesn't suffice. Somewhat ironically (but perfectly understandably, given that it involves no asynchronous execution) neither does
await task;
On the other hand,
await Task.Delay(1);
does seem to be enough, but I'm not clear on whether that's a guarantee or an accident of timing.
To ask the question one more way: is there any (reasonable) code I can write which will guarantee that all continuations for task
have run before proceeding?