Strange case involving TaskContinuationOptions.RunContinuationsAsynchronously

165 views Asked by At
async void Main()
{
    T0.TT();
}

private class T0
{
    [ThreadStatic] private static int test;

    public static async void TT()
    {
        test = 4;
        var continuation = new System.Threading.Tasks.TaskCompletionSource<int>(System.Threading.Tasks.TaskContinuationOptions.RunContinuationsAsynchronously);
        var th = new Thread(() => { Thread.Sleep(500); Console.WriteLine(test); test = 3; continuation.TrySetResult(5); test = 7; });
        th.Start();
        Console.WriteLine(await continuation.Task);
        Console.WriteLine(test);
    }
}
Output:
0
5
3

So without the System.Threading.Tasks.TaskContinuationOptions.RunContinuationsAsynchronously this was written to demonstrate the rest of the async method runs on the thread created by new Thread(). However with System.Threading.Tasks.TaskContinuationOptions.RunContinuationsAsynchronously it still somehow finds that specific [ThreadStatic] value that is set in the newly created thread (thus can't be a TaskScheduler thread) and cleared as soon as TrySetResult returns.

What the hey? How is this happening?

1

There are 1 answers

0
Stephen Cleary On BEST ANSWER

You should be passing TaskCreationOptions.RunContinuationsAsynchronously, not TaskContinuationOptions.RunContinuationsAsynchronously.

Passing TaskContinuationOptions.RunContinuationsAsynchronously will call the overload that takes an object parameter, treating it as a "state" object and not as a flag controlling the TCS behavior.