2017-09-14 110 views
0

我有多个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 
     ) 
    ); 
} 
+0

为什么要使用定时器,而不是简单的'Task's? – Sinatr

+3

给予Task.Run的'Action'只是构造'Timer'对象。因此,只要构建了Timer,任务就完成了。 –

+0

@YacoubMassad这几乎是对这个问题的回答。 –

回答

-1

由于@YacoubMassad在评论中声明,您的任务仅仅是创建计时器并返回。

你可以做的是摆脱计时器什么和使用Task.Delay

return Task.Delay(timeToGo).ContinueWith(t=> executeCustom.AdhockReport(id)); 
+0

嗯...为什么这篇文章被投票了? –

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”。