【问题标题】:How to wait for all Timer Tasks to be done?如何等待所有定时器任务完成?
【发布时间】:2017-09-14 08:28:46
【问题描述】:

我有多个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());

--设置定时器--

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
        )
    );
}

【问题讨论】:

  • 为什么要用定时器而不是简单的Tasks?
  • 给Task.Run 的Action 只是构造了Timer 对象。所以只要Timer 被构造,任务就完成了。
  • @YacoubMassad 这几乎是问题的答案。
  • 你打算什么时候开始计时?=!
  • 如果您发布了有效的代码,那就太好了。你已经声明了todayTask,然后你继续使用它作为todayTasks。

标签: c# multithreading timer


【解决方案1】:

您最好使用适合该工作的工具。我建议使用 Microsoft 的 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"。

【讨论】:

    【解决方案2】:

    正如@YacoubMassad 在评论中所说,您的任务只是创建计时器并返回。

    你可以做的是摆脱计时器并使用Task.Delay:

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

    【讨论】:

      猜你喜欢
      • 2011-03-17
      • 1970-01-01
      • 2017-04-14
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 2023-04-04
      相关资源
      最近更新 更多