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

Roh*_*rma 4 .net c# task task-parallel-library

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

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

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

Jon*_*eet 13

不幸的是,我认为这是措辞.这不是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();
    }
}
Run Code Online (Sandbox Code Playgroud)

每次运行时输出:

DemonstrateIssue thread: 3
Inner task thread: 3
Run Code Online (Sandbox Code Playgroud)

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

  • @Gusdor:是的,绝对的.如果你考虑到"执行任务"它不是很糟糕,但它仍然很容易被误解. (2认同)