首页 > 解决方案 > 一旦引发异常,如何停止等待事件信号

问题描述

我有一些代码需要运行一个新线程来执行一个冗长的任务,检查任务是否已经开始,然后在工作线程异步运行时返回。我是 C# 线程的新手,所以我不知道我这样做是否正确;我的实现是:

线程 1:

  1. 使用 Task.Factory.StartNew() 启动线程 2,传入一个在线程之间共享的 EventWaitHandle 对象。
  2. 调用 eventWaitHandle.WaitOne(); 线程 1 一直等到线程 2 发出就绪信号
  3. 从线程 2 读取一些数据,这些数据在线程 2 发出信号之前填充
  4. 将数据返回给调用者;线程 2 继续在后台运行

线程 2:

  1. 做一些数据库工作,然后在线程 1 和线程 2 之间的共享对象中设置值
  2. 调用 eventWaitHandle.Set() 向线程 1 发送信号
  3. 执行长时间运行的任务

我遇到的问题是线程 2 可能会在使用 eventWaitHandle.Set() 发出信号之前抛出异常并中止。如果发生这种情况,线程 1 将永远等待。作为一种解决方法,我使用 30 秒超时调用 WaitOne,以便线程 1 最终可以放弃等待,然后读取 Task.Exception 对象以查看它是否失败,并处理异常。

问题:

如何在不依赖任意超时值的情况下正确执行此操作?我希望线程 1 等待线程 2 发出信号,但如果线程 2 退出并抛出异常,则立即停止等待。

标签: c#multithreading

解决方案


异步任务方法引发的异常被放置在返回的任务上。仅在等待返回的任务时才触发:

static async Task SomeMethod()
{
   var task = OperationWithException();
   try
   {
     await task;
   }
   catch (InvalidOperationException)
   {
     // exception is correctly to caught here.
   }
}

static async Task OperationWithException()
{
   await Task.Delay(1000);
   // check for it
   throw new InvalidOperationException();
}

推荐阅读