如果任务尚未启动,调用Task.wait可能不会等待?

时间:2014-01-25 11:53:11

标签: c# .net task-parallel-library task

我正在通过c#书阅读Jeffrey Richter的clr并感到不舒服,因为任务等待可能并不总是等待我引用

  

“当线程调用Wait方法时,系统会检查Task是否正常   线程正在等待的已经开始执行。如果有,那么   调用Wait的线程将阻塞,直到Task完成   运行。但如果任务还没有开始执行,那么   系统可以(取决于TaskScheduler)执行任务   使用调用Wait的线程。如果发生这种情况,那么线程   调用Wait不会阻塞;它执行任务并返回   立即“。

有人可以分享更多见解,在这种情况下可能会出现这种情况吗?

1 个答案:

答案 0 :(得分:12)

我认为这是不幸的措辞。并不是Wait调用在任务完成执行之前返回;调用Wait的线程可能最终会执行任务本身,而不仅仅是阻塞。

示例代码:

using System;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    static void Main()
    {
        // Make sure DemonstrateIssue is already called in a ThreadPool
        // thread...
        Task task = Task.Run((Action) DemonstrateIssue);
        task.Wait();
    }

    static void DemonstrateIssue()
    {
        Console.WriteLine("DemonstrateIssue thread: {0}",
                          Thread.CurrentThread.ManagedThreadId);
        Action action = () => Console.WriteLine("Inner task thread: {0}",
            Thread.CurrentThread.ManagedThreadId);
        Task task = new Task(action);
        // Calling Start will just schedule it... we may be able to Wait
        // before it actually executed
        task.Start();
        task.Wait();
    }
}

每次运行时输出:

DemonstrateIssue thread: 3
Inner task thread: 3

这利用了以下事实:线程池不会根据需要立即启动线程 - 等待一段时间以查看现有线程在启动另一个线程之前是否可用。如果您在调用Thread.Sleep(5000);之前添加task.Wait(),则会看到这两项任务最终会出现在不同的主题上。