【发布时间】:2016-09-12 19:38:45
【问题描述】:
在我的应用程序中,我需要在某个设定的时间间隔内不断处理Work 的一些片段。我最初写了一个Task 来不断检查给定的Task.Delay 以查看它是否已完成,如果是这样,将处理与Task.Delay 对应的Work。这种方法的缺点是当没有完成Task.Delay 时,检查这些Task.Delays 的Task 将处于伪无限循环中。
为了解决这个问题,我发现我可以创建一个“递归Task”(我不确定这方面的术语是什么),它可以根据需要在给定的时间间隔内处理工作。
// New Recurring Work can be added by simply creating
// the Task below and adding an entry into this Dictionary.
// Recurring Work can be removed/stopped by looking
// it up in this Dictionary and calling its CTS.Cancel method.
private readonly object _LockRecurWork = new object();
private Dictionary<Work, Tuple<Task, CancellationTokenSource> RecurringWork { get; set; }
...
private Task CreateRecurringWorkTask(Work workToDo, CancellationTokenSource taskTokenSource)
{
return Task.Run(async () =>
{
// Do the Work, then wait the prescribed amount of time before doing it again
DoWork(workToDo);
await Task.Delay(workToDo.RecurRate, taskTokenSource.Token);
// If this Work's CancellationTokenSource is not
// cancelled then "schedule" the next Work execution
if (!taskTokenSource.IsCancellationRequested)
{
lock(_LockRecurWork)
{
RecurringWork[workToDo] = new Tuple<Task, CancellationTokenSource>
(CreateRecurringWorkTask(workToDo, taskTokenSource), taskTokenSource);
}
}
}, taskTokenSource.Token);
}
应该/可以用Task.ContinueWith 的链来表示吗? 这样的实现有什么好处吗?当前的实现有什么重大问题吗?
【问题讨论】:
-
你应该使用
ConcurrentDictionary。 -
您的“重复任务”只是循环中效率较低的版本
await。 (但首先不要这样做) -
@KDecker:不,你应该使用
await而不是ContinueWith。
标签: c# recursion task-parallel-library