繁体   English   中英

什么时候处理带有子任务的System.Threading.Task?

[英]When to dispose of System.Threading.Task with child tasks?

我有一个任务,启动几个子任务。 (例如,任务A创建B,C,D,E,F)。 我还创建了一个System.Threading.Timer来每10秒轮询一次数据库,以检查是否已按请求取消了计划的项目。 如果是,则设置CancellationTokenSource以便任务知道取消。 每个子任务(在本例中为B,C,D,E,F)将在适当时取消(它们通过文件循环并移动它们)。

由于Task实现了IDisposable ,我想知道从catch块再次调用Task.WaitAll是否是个好主意,等待取消传播。 在处理取消请求时,子任务可能处于循环的中间,并且在完成之前不能取消

但是,根据MSDN:

始终在释放对任务的最后一个引用之前调用Dispose。 否则,在垃圾收集器调用Task对象的Finalize方法之前,不会释放它正在使用的资源。

我应该在我的任务数组上再次调用wait,以便在数组中的每个任务上正确调用Dispose()吗?

public class MyCancelObject
{
  CancellationTokenSource Source { get;set;}
  int DatabaseId { get;set;}   
}

private void CheckTaskCancelled(object state)
{
  MyCancelObject sourceToken = (MyCancelObject)state;

  if (!sourceToken.CancelToken.IsCancellationRequested)
  {
    //Check database to see if cancelled -- if so, set to cancelled
    sourceToken.CancelToken.Cancel();
  }
}

private void SomeFunc()
{
  Task.StartNew( () =>
  {
    MyCancelObject myCancelObject = new MyCancelObject(
      databaseId,
      new CancellationTokenSource());
    System.Threading.Timer cancelTimer = new Timer(
      new TimerCallback(CheckIfTaskCancelled),
      myCancelObject,
      10000,
      10000);        
    Task[] someTasks = new Task[someNumberOfTasks];

    for (int i = 0; i < someNumberOfTasks; i++)
      someTasks[i] = Task.Factory.StartNew(
        () =>
        {
          DoSomeWork(someObject, myCancelObject.CancelToken.Token);
        },
        TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning,
        myCancelObject.CancelToken.Token);

    try
    {
      Task.WaitAll(someTasks, cts);
    }
    catch (AggregateException)
    {
      //Do stuff to handle
    }
    catch (OperationCanceledException)
    {
      //Should I call Task.WaitAll(someTasks) again??
      //I want to be able to dispose.
    }
  }
}

我觉得我已经想到了这一点,但任何想要添加其他任何有用的东西都非常受欢迎。

我只是从catch块再次调用Task.WaitAll()来等待其他任务完成。 完成后,我有一个finally块清理阵列中的所有任务。

try
{
Task.WaitAll(someTaskArray, cancelToken)
}
catch (OperationCanceledException)
{
Task.WaitAll(someTaskArray);
}
finally
{
for (int i = 0; i < someTaskArray.Length; i++)
someTaskArray[i].Dispose();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM