Search code examples
c#windows-runtimetaskdelayasync-await

C# task "finishes" at Task.Delay? (WinRT)


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?


Solution

  • 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.