涉及 TaskContinuationOptions.RunContinuationsAsynchronously 的奇怪案例

问题描述

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

因此,如果没有 System.Threading.Tasks.TaskContinuationoptions.runcontinuationsAsynchronously,编写此代码是为了演示 async 方法的其余部分在由 new Thread() 创建的线程上运行。但是,对于 System.Threading.Tasks.TaskContinuationoptions.runcontinuationsAsynchronously,它仍然以某种方式找到在新创建的线程(因此不能是 TaskScheduler 线程)中设置的特定 [ThreadStatic] 值,并在 TrySetResult 返回后立即清除。

嘿嘿?这是怎么回事?

解决方法

您应该传递TaskCreationOptions.RunContinuationsAsynchronously,而不是TaskContinuationOptions.RunContinuationsAsynchronously

传递 TaskContinuationOptions.RunContinuationsAsynchronously 将调用 overload that takes an object parameter,将其视为“状态”对象,而不是控制 TCS 行为的标志。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...