Task.Factory.StartNew()是否保证至少创建一个新线程?

时间:2012-02-23 10:12:01

标签: c# multithreading threadpool task-parallel-library

据我所知,TPL不一定为并行集中的每个任务创建一个新线程,但是它总是创建至少一个吗?例如:

private void MyFunc()
{
    Task.Factory.StartNew(() =>
    {
        //do something that takes a while   
    });

    DoSomethingTimely();   //is this line guaranteed to be hit immediately?
}

编辑:澄清:是的,我的意思是保证执行MyFunc()的线程不会用于执行//do something that takes a while

6 个答案:

答案 0 :(得分:7)

这取决于当前的默认TaskScheduler。您可以设想某人做一些可怕的事情,例如在SynchronousTaskScheduler期间实施执行任务主体的QueueTask并在返回之前将其设置为完成。

假设你没有让其他人弄乱你的任务调度员,你不必担心它。

答案 1 :(得分:5)

这取决于“立即”的含义,但我认为假设TPL不会劫持您当前正在执行的线程来同步运行任务中的代码是合理的,如果这就是你的意思。至少没有普通的调度程序...你可以编写自己的调度程序这样做,但你通常可以假设StartNew安排任务而不仅仅是内联运行。

答案 2 :(得分:2)

您的主要问题和代码中的问题是完全不同的问题。但这两个问题的答案是:

1)不,不能保证线程将被启动。创建和启动的是任务。最终,某些线程必须执行该任务,但是否将创建一个未指定。可以重用现有的线程。

2)这取决于你的意思“立即”。严格来说,没有及时性保证。但是你已经告诉系统执行那个任务,一旦它完成它认为更重要的一切,它至少会启动它。不保证严格的公平性或及时性。

答案 3 :(得分:1)

是的,在调度任务运行后很快就会命中。

不,它不会创建新线程,而是声明一个。当他们说它并不总是创建一个新线程时,他们指的是它重用了线程池中的线程。

池的大小取决于检测到的CPU核心数。但它始终包含至少1个线程。 ;)

答案 4 :(得分:1)

简而言之:是的,这是有保证的。

更长:如果StartNew() 创建新主题,它将重用另一个主题:无论是免费还是排队。

答案 5 :(得分:0)

DoSomethingTimely会很快被调用,但是这与创建新线程或将任务添加到队列有什么关系呢?