Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何保证在使用Task.StartNew方法时创建新线程_C#_.net_Multithreading_.net 4.0_Task Parallel Library - Fatal编程技术网

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

C# 如何保证在使用Task.StartNew方法时创建新线程,c#,.net,multithreading,.net-4.0,task-parallel-library,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 pr

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

目前我是这样做的:

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
    }
 }
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
   }
}
这总是为我创建一个新的线程。然而,经过多次讨论后,即使它被标记为LongRunning,也不能保证会创建一个新线程

过去我做过这样的事情:

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
    }
 }
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
   }
}
您是否建议我回到这种方法以保证使用新线程?

您必须指定为什么“始终需要单独的线程”

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


但通常,CheckFiles()方法将在另一个(而不是调用)线程上执行。问题在于该线程是否是专门创建的,或者它是否可能(连续)在多个线程上执行


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

默认任务调度程序
ThreadPoolTaskScheduler
确实总是为长时间运行的任务创建新线程。正如您所看到的,它不使用线程池。这与手动创建线程没有什么不同。从理论上讲,.NET4.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);
  }
}

这取决于您使用的调度程序。有两种常用实现,ThreadPoolTaskScheduler和SynchronizationContextTaskScheduler。后者根本不启动由FromCurrentSynchronizationContext()方法使用的线程


ThreadPoolTaskScheduler就是您得到的。它确实使用了LongRunning选项,如果设置了,它将使用常规线程。重要的是要避免饥饿其他TP线程。您将获得一个没有该选项的TP线程。这些是实现细节,如有变更,恕不另行通知,虽然我认为它不太可能很快。

< P> LongRunning只是对调度器的暗示——如果您必须始终有一个新线程,您必须创建一个。

我需要一个单独的线程写入另一个线程上的文件,以便让调用线程执行它想要的操作。我可能需要另一个线程来处理套接字接收的数据。在这两种情况下,数据都将添加到队列中,然后在另一个线程上退出队列,让调用线程自由地执行其他操作。如果您只允许,调度程序将完全执行您需要的操作。但我如何保证这一点。你怎么知道调度程序会在另一个线程上为我这样做?还有一件事我没有具体说明,而你要做的就是任务。等等。因为我想在另一个线程上使用它,所以我不等待()@Jon-你还没有解释为什么你“需要一个新线程”。它和“一条单独的线”混淆了。无论如何,您现在走错了方向。当您需要保证另一个线程时的示例:您从
SetWindowsHookEx
获得回调,并且您需要执行COM调用,例如WMI API。如果在回调中执行此操作,则会出现一个异常:由于应用程序正在发送输入同步调用,因此无法进行传出调用。你必须保证在一个单独的线程上运行你需要的任何东西。
longlunning
只是对调度程序的一个提示-如果你一定要一直有一个新线程,你就必须创建一个。想把它作为一个答案吗?我想一个常见的困惑点是答案中没有答案的地址,它不能保证生成一个新线程,但它将始终使用线程池中的线程,它可能只是重用池中空闲的线程,而不做任何工作。如果您从非线程池线程调用
Task.Factory.StartNew
,它将始终在不同的线程上运行代码,您只是不知道该线程是全新的,还是以前用于运行其他代码。我看不出我的回答有什么问题。你能详细解释一下你为什么要投否决票吗?@Ramhound我知道这很古老,但是xp!=回答正确。阿洛伊斯是对的,请参阅.NET Framework sourcecode以了解
ThreadPoolTaskScheduler
-第二种方法down
QueueTask
:referencesource.microsoft.com/#mscorlib/system/threading/Tasks/ThreadPoolTaskScheduler.cs甚至在代码中有一条注释://在自己的专用线程上运行LongRunning任务。我认为这是正确的答案。我喜欢使用Task抽象线程,但没有人能保证有一个新线程。Henk说我应该让它做我想做的,但这并不保证会有一个新的线程。你认为Henk说我走错了方向是正确的吗?如果是的话,我想知道/了解更多。我想混淆的是像“保证”这样的词。
LongRunning
选项根本不能“保证”做任何事情。然而,.NET4中的默认TaskScheduler确实创建了一个新线程,这不太可能改变。使用任务是一种使代码更容易的抽象,但是您确实会失去一些控制。如果这对你真的很重要,那么你可以编写一个TaskScheduler来保证一个新的线程,并兼得这两个方面的优点:)有趣的想法。我在创建和管理线程方面没有问题,我只是认为现在的重点是让TPL为您做这件事,但如果它不能保证新线程,那么您的选择/答案会更好。我也不确定Henk所说的独立线程和新线程之间的区别是什么意思。当然,这是一样的,除非有一个神奇的隐藏线程等着我发布命令让它去做。正如你已经发现的,这里确实有“神奇的”隐藏线程。但真正的问题是,你为什么要保证它将如何执行?如果任务调度器有理由相信可能不需要新线程,那么为什么您会认为您知道得更好?这样的决定背后有很多理论和权衡。为什么我找不到(在线)呢