如何等待所有计时器任务完成?
问题描述:
我有多个System.Threading.Timer
并行启动。最后,我有一个Task.Wait
等待所有任务完成。但它不等所有,我怎样才能让它等待所有?如何等待所有计时器任务完成?
private List<Task> todayTasks = new List<Task>();
foreach (var item in todayReport)
{
todayTasks.Add(SetupTimer(item.Exec_Time, item.Report_Id));
}
Task.WaitAll(todayTasks.ToArray());
--SetupTimer--
private Task SetupTimer(DateTime alertTime, int id)
{
DateTime current = DateTime.Now;
TimeSpan timeToGo = alertTime.TimeOfDay - current.TimeOfDay;
if (timeToGo < TimeSpan.Zero) {
//TODO: ERROR time already passed
}
ExecCustomReportService executeCustom = new ExecCustomReportService();
return Task.Run(
() => new Timer(
x => executeCustom.AdhockReport(id), null, timeToGo, Timeout.InfiniteTimeSpan
)
);
}
答
由于@YacoubMassad在评论中声明,您的任务仅仅是创建计时器并返回。
你可以做的是摆脱计时器什么和使用Task.Delay
:
return Task.Delay(timeToGo).ContinueWith(t=> executeCustom.AdhockReport(id));
+0
嗯...为什么这篇文章被投票了? –
答
你真是最好使用适合于这项工作的工具。我建议微软的Reactive Framework(Rx)。那么你可以这样做:
var query =
from item in todayReport.ToObservable()
from report in Observable.Start(() => executeCustom.AdhockReport(item.Report_Id))
select report;
IDisposable subscription =
query
.Subscribe(
report =>
{
/* Do something with each report */
},
() =>
{
/* Do something when finished */
});
你只需要NuGet“System.Reactive”。
为什么要使用定时器,而不是简单的'Task's? – Sinatr
给予Task.Run的'Action'只是构造'Timer'对象。因此,只要构建了Timer,任务就完成了。 –
@YacoubMassad这几乎是对这个问题的回答。 –