Task.Factory.StartNew starts with a great delay despite having available threads in threadpool

本秂侑毒 提交于 2019-12-25 03:26:52

问题


This question is a continuation to a previous question I've asked:

It takes more than a few seconds for a task to start running

I now know how exactly to reproduce this scenario. Task.Factory.StartNew is scheduled on the thread pool, so I'm logging the following (just before I invoke the Factory.StartNew):

        int workerThreads = 0;
        int completionPortThreads = 0;
        ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
        ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
        var tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;
         //I HAVE A LOG HERE

        Task task = Task.Factory.StartNew(() =>
        {
          //I HAVE A LOG ALSO HERE, AND THAT'S HOW I KNOW,    
          //THE TASK INVOCATION IS DELAYED, AND THE DALAY IS NOT DUE TO MY CODE WITHIN THE TASK
           // Some action that returns a boolean - **CODE_A**
        }).ContinueWith((task2) =>
        {
            result= task2.Result;
            if (!result)
            {
                //Another action **CODE_B**
            }
        }, token);

When the bug is reproduced, I get 32767 as Max worker threads, and 32756 as available worker threads.

Now, there is something I don't understand. At least as I've understood, once the threadpool reaches its overload, the threadpool will stop creating new threads immediately. And that's probably the reason for the delay of my task (that starts after more than 5 seconds from the invocation of Factory.StartNew).

But when the delay occurs, I see that I have 32756 available worker threads in my threadpool, so why does the threadpool NOT use one of those 32756 available worker threads to start my task immediately?

The available threads are on the ThreadPool (I mean, I invoke ThreadPool.GetAvailableThreads), and Task.Factory.StartNew allocates a task from the threadPool. So, why am I getting this delay despite having available threads in threadpool?


回答1:


It's not the MAX worker threads value you need to look at - it's the MIN value you get via ThreadPool.GetMinThreads().

The max value is the absolute maximum threads that can be active. The min value is the number to always keep active. If you try to start a thread when the number of active threads is less than max (and greater than min) you'll see a 2 second delay.

You can change the minimum number of threads if absolutely necessary (which it is in some circumstances) but generally speaking if you find yourself needing to do that, you might need to think about redesigning your multithreading so that you don't need to.

As the Microsoft documentation states:

By default, the minimum number of threads is set to the number of processors on a system. You can use the SetMinThreads method to increase the minimum number of threads. However, unnecessarily increasing these values can cause performance problems. If too many tasks start at the same time, all of them might appear to be slow. In most cases, the thread pool will perform better with its own algorithm for allocating threads. Reducing the minimum to less than the number of processors can also hurt performance.



来源:https://stackoverflow.com/questions/53589811/task-factory-startnew-starts-with-a-great-delay-despite-having-available-threads

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