Calling Task.wait may not wait if the task has not yet started?

白昼怎懂夜的黑 提交于 2019-12-30 06:57:09

问题


I was reading Jeffrey Richter's clr via c# book and felt uncomfortable reading that task wait may not always wait and I quote

"When a thread calls the Wait method, the system checks if the Task that the thread is waiting for has started executing. If it has, then the thread calling Wait will block until the Task has completed running. But if the Task has not started executing yet, then the system may (depending on the TaskScheduler ) execute the Task by using the thread that called Wait . If this happens, then the thread calling Wait does not block; it executes the Task and returns immediately."

Can some one please share more insight and in which case can such a scenario may happen?


回答1:


I think this is unfortunately phrased. It's not that the Wait call returns before the task has finished executing; it's that the thread calling Wait may end up executing the task itself, rather than just blocking idly.

Sample code:

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();
    }
}

Output every time I've run it:

DemonstrateIssue thread: 3
Inner task thread: 3

This takes advantage of the fact that the thread pool doesn't spin up threads immediately on demand - it waits for a while to see if an existing thread will become available before starting another one. If you add Thread.Sleep(5000); before the call to task.Wait(), you'll see the two tasks end up on different threads.



来源:https://stackoverflow.com/questions/21350177/calling-task-wait-may-not-wait-if-the-task-has-not-yet-started

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!