尽管线程池中有可用线程,但Task.Factory.StartNew的启动仍存在很大的延迟 [英] Task.Factory.StartNew starts with a great delay despite having available threads in threadpool

查看:893
本文介绍了尽管线程池中有可用线程,但Task.Factory.StartNew的启动仍存在很大的延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题是我先前提出的问题的延续:

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

这需要花费更多时间任务开始需要几秒钟的时间

我现在知道如何精确地重现这种情况. Task.Factory.StartNew是在线程池上安排的,因此我正在记录以下内容(就在调用Factory.StartNew之前):

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

重现该错误时,我得到32767作为最大工作线程,32756作为可用工作线程.

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

现在,有些事情我不理解. 至少据我了解,一旦线程池达到其过载,线程池将立即停止创建新线程.这可能是我的任务延迟的原因(从调用Factory.StartNew超过5秒后开始).

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).

但是,当发生延迟时,我看到我的线程池中有32756个可用工作线程,那么为什么线程池不使用那些32756个可用工作线程之一立即启动我的任务?

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?

可用线程在ThreadPool上(我是说,我调用 ThreadPool .GetAvailableThreads),而Task.Factory.StartNew从threadPool分配任务.那么,为什么尽管线程池中有可用线程,但为什么会出现这种延迟?

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?

推荐答案

这不是您需要查看的MAX工作线程值-这是您通过

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

最大值是可以活动的绝对最大线程数.最小值是始终保持活动状态的数字.如果您尝试在活动线程数小于最大数量(大于最小数量)时启动线程,则会看到2秒的延迟.

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.

作为

默认情况下,最小线程数设置为系统上的处理器数.您可以使用SetMinThreads方法来增加最小线程数.但是,不必要地增加这些值可能会导致性能问题.如果太多任务同时开始,则所有任务似乎都很慢.在大多数情况下,线程池将使用其自己的分配线程算法来更好地执行.将最小值减少到少于处理器数量也会损害性能.

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.

这篇关于尽管线程池中有可用线程,但Task.Factory.StartNew的启动仍存在很大的延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆