c# - Task.WaitAll 正在阻塞

标签 c# async-await

我想同时运行两个任务,其中一个任务有一个 Task.Delay() 。

即一种是连续运行,一种是每 15 分钟运行一次。

这是我到目前为止所拥有的:

public class ContinousAndAggregatedCheckRunner<T, T2>                                                             
{
   private readonly int _aggregationInterval;
   private readonly List<T> _collectedData;
   private readonly Func<IEnumerable<T>, Task<T2>> _aggregator;
   private readonly Func<Task<IEnumerable<T>>> _collector;
   private CancellationToken _aggregationToken = default(CancellationToken);
   private CancellationToken _collectionToken = default(CancellationToken);

   public ContinousAndAggregatedCheckRunner(Func<IEnumerable<T>, Task<T2>> aggregator,
                                            int aggregationInterval,
                                            Func<Task<IEnumerable<T>>>)
   {
      _aggregator = aggregator;
      _aggregationInterval = aggregationInterval;
      _collector = collector;
      _collectedData = new List<T>();
   }

   public async Task Run()
   {
       Task.WaitAll(Collect(), Aggregate());     
   }

   private async Task Collect()
   {
      while (!_collectionToken.IsCancellationRequested)
      {
          Console.WriteLine($"Collecting {DateTime.Now.ToLongDateString()} {DateTime.Now.ToLongTimeString()}");
          try
          {
             var results = await _collector();
             _collectedData.AddRange(results);
          }
          catch (TaskCanceledException)
          {
              break;
          }
       }
    }

    private async Task Aggregate()
    {
       while (!_aggregationToken.IsCancellationRequested)
       {
         Console.WriteLine("Aggregating");
                try
                {
                    var aggregate = await _aggregator(_collectedData);
                    var taskFactory = new TaskFactory();
                    await taskFactory.StartNew(() => Send(aggregate), _aggregationToken);
                    _collectedData.Clear();
                    await Task.Delay(TimeSpan.FromMinutes(_aggregationInterval), _aggregationToken);
                }
                catch (TaskCanceledException)
                {
                    break;
                }
            }
        }

问题是,它运行了一点收集。然后它进入 Aggregate() 并停止为 Task.Delay() 执行任何操作,然后它 Sends() 。然后它就不再执行任何操作。

什么都不做,我的意思是 Collect() 停止执行。

我认为在某个时候它会阻塞。

我缺少的是他们的模式吗?我想无限期地运行两个任务,并允许其中一个任务暂停指定的时间,而不影响另一个任务。

最佳答案

有一些问题可以修复。

  1. 正如 Ben Voigt 所说,“WaitAll”确实是一个阻碍,你最好使用 WhenAll 来创建一系列任务
  2. 值得使用 Task.Factory.StartNew 而不是实例化新的 TaskFactory 实例
  3. StartNew 可能根本不是最佳选择,请在此处查看详细信息 https://blog.stephencleary.com/2013/08/startnew-is-dangerous.html

关于c# - Task.WaitAll 正在阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45284327/

相关文章:

asp.net - WebForms 中的 Async/Await - 在页面生命周期结束之前如何继续运行?

c# - 如何使用 Task.WhenAny 并实现重试

c# - 如果文件列表中缺少一个文件,如何评估为 false

c# - 在 Windows 窗体中运行长任务时保持 UI 线程响应

c# - 我的用户控件应该只添加到某种类型的控件

c# - 持久化延迟加载属性

javascript - 尝试理解 setTimeout Promise 等待的顺序

node.js - 在Electron应用程序中使用node-firebird进行除SELECT之外的其他操作时出错

c# - 在 C# 安装项目中完成设置后如何自动启动我的应用程序

c# - 程序运行时阻止 sleep 模式 C#