Reputation: 1181
I ran into this peculiar case with tasks and Task.Factory. So here's my piece of code.
public Task CreateAndStartSyncTask()
{
return Task.Factory.StartNew(async () =>
{
... do stuff ...
await Task.Delay(500);
... do more stuff ...
}
}
public void Synchronize()
{
var syncTask = CreateAndStartSyncTask();
syncTask.Wait(mTimeout);
switch(syncTask.Status) {
case TaskStatus.RanToCompletion:
// VICTORY!
break;
default:
throw syncTask.Exception;
}
}
So here my problem is that when I run this glorious piece of code, I get to the switch case BEFORE "... do more stuff ...". The task then continues running until completion. This is not desired functionality as I would really prefer for the task to complete.
That being said, having it in it's own task here is slightly redundant in this specific context given the fact that it is treated in a synchronous manner but I can't fully disclose the code and I really need to understand the whole task completion mentality.
What's up and how can I actually check whether a task is REALLY concluded?
Upvotes: 0
Views: 665
Reputation: 456457
Don't use Task.Factory.StartNew
. Use Task.Run
instead. Both Stephen Toub and I have blog posts that describe this in detail.
In summary, StartNew
doesn't understand async
methods. The Task
it returns only represents the first synchronous portion of the method. To use StartNew
, you either have to call Unwrap
or do a double await
. It's far better to use Task.Run
, which does understand async
methods.
Also, you don't want to block on async
tasks (i.e., the Wait
in Synchronize
). Instead, you should await
them. If you block on them, you can easily encounter a deadlock situation that I describe on my blog.
Upvotes: 4