未在线程池线程上安排任务继续

Abs*_*lom 5 .net c# continuations asynchronous task

我正在阅读有关SynchronizationContext及其与async/await方法(链接)的使用.根据我的理解,在SynchronizationContext为null的Console应用程序中,将使用默认调度程序(即ThreadPool)调度等待方法(Task)的继续.

但是如果我运行这个控制台应用程序,你会从输出中看到延续是在我创建的工作线程上运行的:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("MainThreadId=" + Thread.CurrentThread.ManagedThreadId);
        Method1().ContinueWith(t =>
        {
            Console.WriteLine("After Method1. ThreadId=" + Thread.CurrentThread.ManagedThreadId);
        });

        Console.ReadKey();
    }

    public static async Task Method1()
    {
        Console.WriteLine("Method1 => Entered. ThreadId=" + Thread.CurrentThread.ManagedThreadId);

        TaskCompletionSource<bool> completionSource = new TaskCompletionSource<bool>();
        Thread thread = new Thread(() =>
        {
            Console.WriteLine("Method1 => Started new thread. ThreadId=" + Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(2000);
            completionSource.SetResult(true);
        });

        thread.Start();

        await completionSource.Task;

        Console.WriteLine("Method1 => After WorkerThread. ThreadId=" + Thread.CurrentThread.ManagedThreadId);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

MainThreadId=10
Method1 => Entered. ThreadId=10
Method1 => Started new thread. ThreadId=11
Method1 => After WorkerThread. ThreadId=11
After Method1. ThreadId=12
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,"After WorkerThread"在与我的workerthread相同的线程上输出,但不在线程池上输出.

我发现了一个类似的问题,但这个人正在使用Mono,他们说这是一个错误.在我这边,我在Visual Studio中构建了这个代码,并在我的机器上安装的Windows 7和.Net 4.5.2下运行它.

有人可以解释一下这种行为吗?

Ste*_*ary 5

这是因为我在博客上记录实现细节:await使用ExecuteSynchronously标志安排创建的延续.在这种情况下,当需要触发延续时(即,在TaskCompletionSource<T>.SetResult工作线程的调用中),默认调度程序首先尝试确定它是否可以在当前线程上运行.

由于工作线程没有TaskScheduler拒绝同步执行任务,因此该ExecuteSynchronously标志将使线程池任务调度程序只是同步执行任务(即,在调用线程上).

  • @Absolom:从技术上讲,它正在线程池任务调度程序中执行.奇怪的行为是由于线程池任务调度程序决定您的线程是其上下文的一部分. (2认同)