我是负责清理与TaskCreationOptions创建的任务后.龙润国旗



当您在指定TaskCreationOptions.LongRunning的同时创建Task时,将专门为该任务创建一个新线程。如果不指定TaskCreationOptions.LongRunning,则使用线程池。

请纠正我,如果我错了,但如果使用线程池,你不需要dispose()任务(只要你没有在任务内使用任何同步对象,如Wait()在子任务上)。

如果是这种情况,我是否负责清理使用TaskCreationOptions.LongRunning标志创建的额外线程?

如果是,以下是可接受的模式:

var task = Task.Factory.StartNew(() => {...}, TaskCreationOptions.LongRunning);
task.ContinueWith(x => task.Dispose());
注意,ContinueWith没有TaskContinuationOptions.LongRunning,所以它应该使用线程池。

话虽如此,但是,我已经读到,将任务状态移动到Completed, FaultedCancelled的线程运行延续的变化很大。

如果有人能指点一下,我会很感激的。

绝对不要在continuation中调用Dispose() -你打算什么时候处理continuation任务?

我知道,Task是可丢弃的唯一原因是清除在等待任务时创建的等待句柄。如果不等待任务,则永远不会创建等待句柄。在任何情况下,终结器最终都会被清除。

同样,如果任务创建了一个新线程,它将自己清理。

TaskContinuationOptions.LongRunning是一个提示任务工厂/调度程序,事情并不像你描绘的那么固定。

我希望ContinueWith在相同的(长运行)线程上执行,可能会或可能不会在ThreadPool上运行。

就我所知,Tasks的清理是自动的,所以我不会在这里使用Dispose()。

我不确定用LongRunning选项创建的Tasks的处置,但是关于您所展示的模式,有一些事情会出现在脑海中。

  1. 如图所示,没有观察到初始的长时间运行的Task,这意味着如果操作由于任何原因抛出Exception,那么它最终将在Finalizer中被重新抛出,这将导致进程崩溃。
  2. Task的文档说你不应该调用Dispose,除非Task已经实际完成。所以你应该检查Task是否在continuation中完成如果你要调用dispose。
  3. 你实际上是在ContinueWith返回的Task上调用Dispose,而不是原来的长时间运行的任务。

你可以这样做:

var task = Task.Factory.StartNew(() => {...}, TaskCreationOptions.LongRunning)
               .ContinueWith(x => 
   if(x.IsFaulted)
   { 
      x.Exception.Handle(_ => true); //just an example, you'll want to handle properly
   }
   else if(x.IsCompleted)
   {
       //do something with the result, if necessary
       x.Dispose());
   }); 

最终,我认为遵守Task比遵守Dispose更重要。

最新更新