Search code examples
c#tasktask-parallel-librarytaskcompletionsource

Why will the synchronous continuations no longer be executed synchronously?


In the following article, Stephen Toub describes how to build a ManualResetEvent using the TPL. In particular, he states that in the following method:

public void Set()
{
    var tcs = m_tcs;
    Task.Factory.StartNew(
        s => ((TaskCompletionSource<bool>)s).TrySetResult(true),
        tcs,
        CancellationToken.None,
        TaskCreationOptions.PreferFairness,
        TaskScheduler.Default);
    tcs.Task.Wait();
}

the tcs.Task.Wait() will "block until the task being completed is actually finished (not including the task’s synchronous continuations, just the task itself)". Why won't we block on any synchronous continuations? That is, what will prevent any synchronous continuations on any Tasks awaiting tcs.Task's completion from executing synchronously?


Solution

  • He means that if you do is this way:

    public void Set()
    {
        m_tsc.TrySetResult(true);
    }
    

    Then all synchronous continuations of TaskCompletionSource Task will run synchronously on this same thread, blocking Set method for the duration.

    However if you do it the way described in your question, then all those continuations will still run, but on thread pool thread, because that's where you execute TrySetResult. As soon as TaskCompletionSource task completes - your tcs.Task.Wait() will return, before synchronous continuations will run. So in effect, Set method will not block waiting for them to complete.