I have the following code in C#, VS2012, WPF 4.5.
My expectation would be that, .ContinueWith
will be executed after the task has finished completely (that's a continuation's whole purpose, isn't it?).
This should result in a value of 2 in finalResult
.
int myTestInt = 0;
Task task = Task.Factory.StartNew(async () =>
{
myTestInt = 1;
await Task.Delay(TimeSpan.FromSeconds(6));
myTestInt = 2;
}).ContinueWith(_ =>
{
int finalResult = myTestInt;
});
In fact, finalResult
is assigned a value of 1 instead. So it seems like the continuation is started on the await
statement already.
Is this the intended behaviour? Am I missing something here? Can't I rely on ContinueWith
to start after a task has completely finished?
Update:
Justin's answer just inspired me to check the following:
int myTestInt = 0;
Task task=Task.Factory.StartNew(async () =>
{
myTestInt = 1;
await Task.Delay(TimeSpan.FromSeconds(6));
myTestInt = 2;
});
task.Wait();
int result2 = myTestInt;
finalResult is still set to 1. Is there no way to reliably wait for a task that contains await
s to complete?
When you pass an
async
delegate toTask.Factory.StartNew
, the returnedTask
only represents the first portion of that delegate (up until the time itawait
s something that is not already completed).However, if you pass an
async
delegate to the newTask.Run
method (which was included for this reason), the returnedTask
represents the entire delegate. So you can useContinueWith
as you expect. (Althoughawait
is usually a better option thanContinueWith
).For more information on
StartNew
vsRun
, see Stephen Toub's post on the topic.I saw this in the MSDN: :-)
So do not forget the "async()" !!!
The await will immediately return control to the calling function, which in this case is the StartNew of your task. This means the task will then complete and execute the ContinueWith. If you really want task to complete before the ContinueWith, then don't await the Task.Delay.