我有一个启动多个子任务的任务。 (例如,任务 A 创建 B、C、D、E、F)。我还创建了一个System.Threading.Timer
每 10 秒轮询一次数据库以检查计划项目是否已按请求取消。如果是,则设置CancellationTokenSource
以便任务知道要取消。每个子任务(在本例中为 B、C、D、E、F)将在适当的时候取消(它们循环遍历文件并移动它们)。
Since Task
实施IDisposable
,我想知道打电话是否是个好主意Task.WaitAll
再次从catch
阻止,等待取消传播。虽然取消请求将被处理,但子任务可能处于循环中间,并且在完成之前无法取消
然而,根据 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.
}
}
}
我觉得我已经弄清楚了这一点,但非常欢迎任何想要添加其他有用内容的人。
我只是简单地打电话Task.WaitAll()
再次从 catch 块等待其他任务完成。当它们全部完成后,我有一个finally块来清理数组中的所有任务。
try
{
Task.WaitAll(someTaskArray, cancelToken)
}
catch (OperationCanceledException)
{
Task.WaitAll(someTaskArray);
}
finally
{
for (int i = 0; i < someTaskArray.Length; i++)
someTaskArray[i].Dispose();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)