使用Task.StartNew方法时如何保证创建新线程

时间:2011-11-07 17:09:21

标签: c# .net multithreading .net-4.0 task-parallel-library

据我所知,我有误导性的信息。我需要在后台运行一个单独的线程。

目前我这样做:

var task = Task.Factory.StartNew
         (CheckFiles
          , cancelCheckFile.Token
          , TaskCreationOptions.LongRunning
          , TaskScheduler.Default);//Check for files on another thread

 private void CheckFiles()
 {
    while (!cancelCheckFile.Token.IsCancellationRequested)
    {
        //do stuff
    }
 }

这总是为我创造一个新线程。但经过多次讨论后,即使将其标记为LongRunning,也不能保证将创建新的线程。

过去我做过类似的事情:

thQueueChecker = new Thread(new ThreadStart(CheckQueue));
thQueueChecker.IsBackground = true;
thQueueChecker.Name = "CheckQueues" + DateTime.Now.Ticks.ToString();
thQueueChecker.Start();


private void CheckQueue()
{
   while (!ProgramEnding)
   {
            //do stuff
   }
}

你会建议我回到这种方法来保证使用新线程吗?

3 个答案:

答案 0 :(得分:16)

默认任务调度程序ThreadPoolTaskScheduler确实总是为长时间运行的任务创建新线程。您可以看到它不使用线程池。与自己创建线程的手动方法没有什么不同。从理论上讲,.NET 4.5的线程调度程序可能会发生不同的事情,但实际上它不太可能发生变化。

protected internal override void QueueTask(Task task)
{     
  if ((task.Options & TaskCreationOptions.LongRunning) != TaskCreationOptions.None)
  {
    new Thread(s_longRunningThreadWork) { IsBackground = true }.Start(task);
  }
  else
  {
    bool forceGlobal = 
        (task.Options & TaskCreationOptions.PreferFairness) != TaskCreationOptions.None;
     ThreadPool.UnsafeQueueCustomWorkItem(task, forceGlobal);
  }
}

答案 1 :(得分:8)

这取决于您使用的调度程序。有两个库存实现,ThreadPoolTask​​Scheduler和SynchronizationContextTaskScheduler。后者根本不启动一个线程,由FromCurrentSynchronizationContext()方法使用。

ThreadPoolTask​​Scheduler就是你得到的。确实使用了LongRunning选项,如果设置了它将使用常规Thread。重要的是要避免使其他TP线程匮乏。你会得到一个没有选项的TP线程。这些是实施细节,如有更改,恕不另行通知,但我认为不太可能很快。

答案 2 :(得分:4)

您必须指定为什么您“总是需要一个单独的线程”。

void Main()
{
   var task = Task.Factory.StartNew(CheckFiles, 
     cancelCheckFile.Token, 
     TaskCreationOptions.LongRunning, 
     TaskScheduler.Default);

   task.Wait();
}

智能调度程序将在此处使用1个线程。为什么不呢?


但一般来说,CheckFiles()方法将在另一个(而不是调用)线程上执行。问题在于是否特别创建了该线程,或者它是否甚至可以在多个线程上执行(连续)。

当您使用任务时,您放弃对线程的控制。这应该是一件好事。