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

C# Task.Factory.StartNew()是否保证至少创建一个新线程?,c#,multithreading,threadpool,task-parallel-library,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? } 编辑:澄清:

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

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

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

编辑:澄清:是的,我的意思是保证执行MyFunc的线程不会被用来执行//做一些需要一段时间的事情。

这取决于您所说的立即执行,但我认为假设TPL不会劫持您当前正在执行的线程以同步运行任务中的代码是合理的,如果你是这个意思的话。至少在正常的调度程序中不是这样。。。您可以编写自己的调度程序,这样做,但是,您通常可以假设StartNew将调度任务,而不仅仅是内联运行任务。

这取决于您所说的立即,但我认为,如果您的意思是这样的话,可以合理地假设TPL不会劫持您当前正在执行的线程来同步运行任务中的代码。至少在正常的调度程序中不是这样。。。您可能会编写自己的调度程序来执行此操作,但您通常可以假定StartNew将调度任务,而不仅仅是内联运行任务。

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

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

是的,它会在分派任务运行后很快命中

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


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

是的,它将在分派任务运行后很快命中

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


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

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


更长:如果StartNew不创建新线程,它将重用另一个线程:通过空闲或排队。

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


更长:如果StartNew不创建新线程,它将重用另一个线程:要么通过释放线程,要么通过排队。

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

1不,不能保证线程会启动。创建和启动的是一项任务。最终,某些线程将不得不执行该任务,但是否创建一个尚不确定。可以重新使用现有线程


这取决于你说的立即是什么意思。严格来说,没有时效性保证。但是您已经告诉系统执行该任务,并且它至少会在完成它认为更重要的一切后立即启动它。严格的公平性或及时性是不能保证的。

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

1不,不能保证线程会启动。创建和启动的是一项任务。最终,某些线程将不得不执行该任务,但是否创建一个尚不确定。可以重新使用现有线程


这取决于你说的立即是什么意思。严格来说,没有时效性保证。但是您已经告诉系统执行该任务,并且它至少会在完成它认为更重要的一切后立即启动它。严格的公平性或及时性是不能保证的。

这取决于当前的违约情况。您可以想象某人正在做一些可怕的事情,比如实现SynchronousTaskScheduler,它在QueueTask期间执行任务体,并在返回之前将其设置为完成


假设你不让别人干扰你的任务调度程序,你就不必担心了。

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


假设你不让别人干扰你的任务调度程序,你就不必担心了。

听起来你并不是在问你真正的问题。为什么要关心是否创建了新线程?在这种情况下,立即意味着什么?听起来你并不是在问你真正的问题。为什么要关心是否创建了新线程?在这种情况下,立即意味着什么?+1如果我同意,我会投票两次
uld,因为它是目前唯一一个提到TaskScheduler类的答案。+1如果可以的话,我会对此投票两次,因为它是目前唯一一个提到TaskScheduler类的答案。对于.NET 4.5,这是否发生了变化?因为我遇到了这种情况,而TPL确实使用了当前正在执行的线程来执行任务。@CameronMacFarland:有一些情况会发生这种情况,但在上面代码中显示的示例中没有。特别是,如果您在启动任务之后直接等待它,然后它才真正开始执行,并且您已经在线程池线程中,我相信您可以重用thread.Nevermind。事实证明,如果任务是在另一个任务中创建的,则该任务可以在其启动的同一线程上执行。请参见编辑:是的,事情就是这样。@CameronMacFarland:它可以在同一个线程上执行,但我不相信它会劫持当前线程来执行。你所指的页面实际上似乎更多地是关于安排连续性,而不是其他任何东西-这是非常不同的。嗯,好的观点。我不知道为什么在4.0中运行的代码会在4.5中崩溃。但这是由于任务在UI线程上执行,而它本不应该执行。对于.NET 4.5,这是否发生了变化?因为我遇到了这种情况,而TPL确实使用了当前正在执行的线程来执行任务。@CameronMacFarland:有一些情况会发生这种情况,但在上面代码中显示的示例中没有。特别是,如果您在启动任务之后直接等待它,然后它才真正开始执行,并且您已经在线程池线程中,我相信您可以重用thread.Nevermind。事实证明,如果任务是在另一个任务中创建的,则该任务可以在其启动的同一线程上执行。请参见编辑:是的,事情就是这样。@CameronMacFarland:它可以在同一个线程上执行,但我不相信它会劫持当前线程来执行。你所指的页面实际上似乎更多地是关于安排连续性,而不是其他任何东西-这是非常不同的。嗯,好的观点。我不知道为什么在4.0中运行的代码会在4.5中崩溃。但这是由于任务在UI线程上执行,而它本不应该这样做。