如何等待多个 C# 事件?

Posted

技术标签:

【中文标题】如何等待多个 C# 事件?【英文标题】:How to wait for multiple C# events? 【发布时间】:2020-08-31 21:01:03 【问题描述】:

我想为以下问题找到一个好的解决方案。 例如,我有 5 个计时器,我从 1 个线程开始。这些计时器在几秒钟后完成它们的工作(这是一种重试机制)。我想等待所有的计时器完成他们的工作。

所以问题是,有什么好的模式可以解决这个问题吗?或者你现在是不是一个布尔集合的好解决方案,如果所有元素都是真的,那么所有的计时器都完成了:D

提前感谢您的回答!

【问题讨论】:

你启动了多少个定时器? "...我有 5 个计时器..." - 一定是错字,好吧,有 5 个计时器。 "...这些计时器..." - 哦,看起来实际上有 1 个计时器。 " 完成他们的 工作" - 不,5 个计时器。 “...这是一个重试机制...” - 嗯,5个重试机制的计时器?我想它实际上是一个计时器。 “...等待所有计时器...” - 哦,伙计:( @vasily.sib 尽管有错字,但仍有 2 人理解我的问题 :) 下次我会更加注意,我保证;) 【参考方案1】:

这听起来你真的想使用Task 而不是Timer

愚蠢的例子:

async Task DoAsync()

  var allTheWork = new []  Work(), Work(), Work() ;

  await Task.WhenAll(allTheWork);

  // Did all the sub-tasks return true?
  if (allTheWork.All(i => i.Result))
  
  


async Task<bool> Work()

  var retries = 3;
  while (retries-- > 0)
      
    if (success) return true;

    await Task.Delay(2000); // This is the timer; you can find better retry patterns of course
  

  return false;

【讨论】:

这正是我想要的。非常感谢。 @Xsayar 当你做Task.WhenAll(tasks)intellitect.com/catching-exceptions-tasks-whenall时要小心异常处理【参考方案2】:

您的问题有多种解决方案。

如果您熟悉 linq,我建议您看一下 Rx(反应式扩展),因为它们使用非常相似的语法。 Rx 允许您对各种事件做很多事情。

另一种方法是使用TPL(任务并行库)如下:

var timer1 = Task.Delay(1000);
var timer2 = Task.Delay(2000);
var timer3 = Task.Delay(3000);
await Task.WhenAll(timer1, timer2, timer3);

请注意,您必须从异步上下文中调用它。如果您不熟悉 async/await,我建议您看一下。如果您不想/不能看它,您可以简单地执行以下操作:

Task.WhenAll(timer1, timer2, timer3).GetAwaiter().GetResult();

【讨论】:

我可以从这个答案中使用“GetAwaiter().GetResult()”。这是一个巨大的帮助,谢谢,这有助于理解。

以上是关于如何等待多个 C# 事件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中等待单个事件,带有超时和取消

如何在同一个块中等待多个块事件

C#多线程:深入了解线程同步lock,Monitor,Mutex,同步事件和等待句柄(中)

等待多个并发事件完成的模型

如何在 c# 中运行多个任务并在完成这些任务时获取事件?

多个线程等待一个事件?