[英]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.