c# - 一旦引发异常,如何停止等待事件信号
问题描述
我有一些代码需要运行一个新线程来执行一个冗长的任务,检查任务是否已经开始,然后在工作线程异步运行时返回。我是 C# 线程的新手,所以我不知道我这样做是否正确;我的实现是:
线程 1:
- 使用 Task.Factory.StartNew() 启动线程 2,传入一个在线程之间共享的 EventWaitHandle 对象。
- 调用 eventWaitHandle.WaitOne(); 线程 1 一直等到线程 2 发出就绪信号
- 从线程 2 读取一些数据,这些数据在线程 2 发出信号之前填充
- 将数据返回给调用者;线程 2 继续在后台运行
线程 2:
- 做一些数据库工作,然后在线程 1 和线程 2 之间的共享对象中设置值
- 调用 eventWaitHandle.Set() 向线程 1 发送信号
- 执行长时间运行的任务
我遇到的问题是线程 2 可能会在使用 eventWaitHandle.Set() 发出信号之前抛出异常并中止。如果发生这种情况,线程 1 将永远等待。作为一种解决方法,我使用 30 秒超时调用 WaitOne,以便线程 1 最终可以放弃等待,然后读取 Task.Exception 对象以查看它是否失败,并处理异常。
问题:
如何在不依赖任意超时值的情况下正确执行此操作?我希望线程 1 等待线程 2 发出信号,但如果线程 2 退出并抛出异常,则立即停止等待。
解决方案
异步任务方法引发的异常被放置在返回的任务上。仅在等待返回的任务时才触发:
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();
}
推荐阅读
- mysql - SQL - 根据成绩类型计算加权学生成绩
- xaml - UWP 如何设置 AutoSuggestBox Suggestions 的打开方向?
- javascript - Vue Computed Method - 在数组中查找值不起作用
- react-native - goBack转换的react-navigation更改持续时间
- python - 使用列表推导或嵌套循环更有效吗?
- php - 从数据库中获取和显示数据(用户)的问题
- r - R - 列出目录中的文件,模式除外
- java - 将paypal集成到android中
- python - 究竟什么是“输出”?
- javascript - 文件名的正则表达式字符串模式