为什么不要使用 async void

问题

在使用 Abp 框架的后台作业时,当后台作业抛出异常,会导致整个程序崩溃。在 Abp 框架的底层执行后台作业的时候,有 try/catch 语句块用来捕获后台任务执行时的异常,但是在这里没有生效。

原始代码如下:

public class TestAppService : ITestAppService
{
private readonly IBackgroundJobManager _backgroundJobManager;

public TestAppService(IBackgroundJobManager backgroundJobManager)
{
_backgroundJobManager = backgroundJobManager;
}

public Task GetInvalidOperationException()
{
throw new InvalidOperationException("模拟无效操作异常。");
}

public async Task<string> EnqueueJob()
{
await _backgroundJobManager.EnqueueAsync<BG, string>("测试文本。");

return "执行完成。";
}
}

public class BG : BackgroundJob<string>, ITransientDependency
{
private readonly TestAppService _testAppService;

public BG(TestAppService testAppService)
{
_testAppService = testAppService;
}

public override async void Execute(string args)
{
await _testAppService.GetInvalidOperationException();
}
}

调用接口时的效果:

640?wx_fmt=png

原因

出现这种情况是因为任何异步方法返回 void 时,抛出的异常都会在 async void 方法启动时,处于激活状态的同步上下文 (SynchronizationContext) 触发,我们的所有 Task 都是放在线程池执行的。

所以在上述样例当中,此时 AsyncVoidMethodBuilder.Create() 使用的同步上下文为 null ,这个时候 ThreadPool 就不会捕获异常给原有线程处理,而是直接抛出。

线程池在底层使用 AsyncVoidMethodBuilder.Craete() 所拿到的同步上下文,所捕获异常的代码如下:

internal static void ThrowAsync(Exception exception, SynchronizationContext targetContext)
{
var edi = ExceptionDispatchInfo.Capture(exception);


if (targetContext != null)
{
try
{
targetContext.Post(state => ((ExceptionDispatchInfo)state).Throw(), edi);
return;
}
catch (Exception postException)
{
edi = ExceptionDispatchInfo.Capture(new AggregateException(exception, postException));
}
}
}

虽然你可以通过挂载 AppDoamin.Current.UnhandledException 来监听异常,不过你是没办法从异常状态恢复的。

参考文章:

Stephen Cleary:https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

Jerome Laban's:https://jaylee.org/archive/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void.html

布鲁克石:https://www.cnblogs.com/brookshi/p/5240510.html

解决

可以使用 AsyncBackgroundJob<TArgs> 替换掉之前的 BackgroundJob<TArgs> ,只需要实现它的 Task ExecuteAsync(TArgs args) 方法即可。

public class BGAsync : AsyncBackgroundJob<string>,ITransientDependency
{
private readonly TestAppService _testAppService;

public BGAsync(TestAppService testAppService)
{
_testAppService = testAppService;
}

protected override async Task ExecuteAsync(string args)
{
await _testAppService.GetInvalidOperationException();
}
}

原文地址:https://www.cnblogs.com/myzony/p/10647460.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 
640?wx_fmt=jpeg


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2018-2019 ICPC Northwestern European Regional Programming Contest (NWERC 2018)

2018-2019 ICPC Northwestern European Regional Programming Contest (NWERC 2018) 题号题目知识点难度AAccess PointsBBrexit NegotiationsCCircuit Board DesignDDate PickupEEquality ControlFFastest SpeedrunGGame DesignHHard DriveIInflationJJinxed BettingKKleptogr…

LCA。。。

树链剖分 #include<cstdio> #include<iostream> #include<cstring> using namespace std; const int N5e510;int h[N],e[2*N],ne[2*N],idx0; void add(int u,int v){e[idx]v,ne[idx]h[u],h[u]idx;return;}int siz[N],de[N],son[N],top[N],fa[N],id[N],num; …

张队长主讲这堂 .NET Core技术培训公开课,太原你约不约

这堂.NET Core技术培训课&#xff0c;你不能错过各位开发者朋友们想必也能体会到&#xff0c;现在市面上关于.NET Core的培训课程少之又少&#xff0c;其中有质量有内容的课程更是凤毛麟角&#xff0c;良师难遇&#xff0c;一课难求。但是现在&#xff0c;机会来了。中微云孵邀…

L :WeChat Walk

详见代码 #include<cstdio> #include<iostream> #include<cstring> #include<vector> #include<map> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; const int N2e510;int h[N],e[N<<1],…

微软推出新语言Bosque,超越结构化程序设计

微软近期推出了一款全新的编程语言 Bosque&#xff0c;该语言参考了 TypeScript 的语法与类型&#xff0c;还有 ML 和 Node/JavaScript 的语义。作者微软计算机科学家 Mark Marron 致力于消除编程过程中出现的各种复杂情况&#xff0c;创造出了他认为超越主流结构化程序设计的 …

Acwing202. 最幸运的数字

Acwing202. 最幸运的数字 题意&#xff1a; 现在给定一个正整数 L&#xff0c;请问至少多少个 8 连在一起组成的正整数&#xff08;即最小幸运数字&#xff09;是 L 的倍数。 题解&#xff1a; x个8连在一起组成的正整数可写作8(10x−1)/98(10^x-1)/98(10x−1)/9。现在要求…

Black and white

在1-n&#xff0c;1-m里选nm-1个边&#xff0c;不形成环的话那就可以补全图形。。。还是不懂 #include<iostream> #include<cstring> using namespace std; const int N6000; typedef long long ll; int l[N],r[N],A[N*N]; int ma[N][N],dis[NN]; int n,m,a,b,c,…

Sumdiv POJ - 1845

Sumdiv POJ - 1845 题意&#xff1a; 求ABA^BAB的所有约数之和mod 9901(1<A,B<5e7) 题解&#xff1a; 我们先将A分解质因子&#xff0c;表示为&#xff1a;p1c1∗p2c2∗......∗pncnp_{1}^{c_{1}}*p_{2}^{c_{2}}*......*p_{n}^{c_{n}}p1c1​​∗p2c2​​∗......∗pn…

vue 实验报告8 基于Nuxt.js开发一个Vue程序,实现登录和注册切换

一、步骤&#xff1a; 保证node.js版本在14以上 1. 全局安装create-nuxt-app: npm install -g create-nuxt-app2.9.x 2. 创建项目: create-nuxt-app my-nuxt-demo 选项这么选&#xff1a; 然后输入&#xff1a; cd my-nuxt-demo 3. 创建登录和注册页面: 在/pages目录下创建logi…

解决vs2019中暂时无法为.net core WinForms使用 Designer 的临时方法

以下方法来自于微软github开源项目WinForms:dotnet/winforms - Using the Classic WinForms Designer in WinForms Core, 请放心使用 .目前.net core下的 Windows Forms的可视化设计器(Designer)尚不可用&#xff0c;后续的Visual Studio 2019 Update才会支持该部分的功能。不过…

P2480 [SDOI2010]古代猪文(数论好题)

P2480 [SDOI2010]古代猪文 题意&#xff1a; 给你n和g&#xff0c;求g∑d∣nCndmodpg^{\sum_{d|n}C_{n}^{d}}\bmod pg∑d∣n​Cnd​modp p999911659 题解&#xff1a; 这个一个综合性很强的数论题 涉及到欧拉定理&#xff0c;Lucas定理&#xff0c;中国剩余定理&#xff0c…

ASP.NET Core开发者成长路线图

来源: MoienTajik/AspNetCore-Developer-Roadmap.2019年ASP.NET Core开发者指南:你可以在下面找到一张图&#xff0c;该图展示了你可以选取的路径及你想学习的库&#xff0c;从而成为一名 ASP.NET Core 开发者。“作为 ASP.NET Core 开发者&#xff0c;我接下来应该学习什么&am…

P2183 [国家集训队]礼物(扩展卢卡斯)

P2183 [国家集训队]礼物 题意&#xff1a; 有n个礼物&#xff0c;分给m个人&#xff0c;分给第i个人的礼物数量是wi&#xff0c;问送礼物的方案数。 题解&#xff1a; 扩展卢卡斯模板题 很容易看出和组合数有关的题目&#xff0c;对于总方案&#xff0c;完美可以将其分解为…

Eyjafjalla

区间查询有关比大小的数目&#xff0c; 主席树感觉学线段树的时候不用x<<1,x<<1|1去建一次树那样就容易理解多了&#xff1b; #include<cstdio> #include<iostream> #include<cstring> #include<vector> #include<queue> #include…

P4345 [SHOI2015]超能粒子炮·改

P4345 [SHOI2015]超能粒子炮改 题意&#xff1a; 求解式子∑i0kCni%p\sum_{i0}^{k}C_{n}^{i} \% p∑i0k​Cni​%p n,k<1e18 题解&#xff1a; 设f(n,k)∑i0kCnif(n,k)\sum_{i0}^{k}C_{n}^{i}f(n,k)∑i0k​Cni​ 开始化简&#xff1a; 由卢卡斯定理得&#xff1a; f(n,k)…

.NET Framework VS .NET Core

本文对应的原文来至 c-sharpcorner 的一篇文章&#xff0c;文末有链接。如有错误&#xff0c;还请指正。前言你会为你的下一个应用程序选择哪一种开发平台 - .NET Framework 或者 .NET Core&#xff1f;在这篇文章中&#xff0c;让我们比较一下这两个开发平台的特点&#xff0c…

P6669 [清华集训2016] 组合数问题

P6669 [清华集训2016] 组合数问题 题意&#xff1a; 给你n&#xff0c;m&#xff0c;k&#xff0c;问有多少对(i,j)满足K∣CijK|C_{i}^{j}K∣Cij​ (Cij是k的倍数C_{i}^{j}是k的倍数Cij​是k的倍数) n,m<1e18 题解&#xff1a; n和m非常大&#xff0c;非常非常大&#x…

解决 VS2019 中.net core WPF 暂时无法使用 Designer 的临时方法

以下方法来自于微软github开源项目WPF:dotnet/samples - WPF Hello World sample with linked files&#xff0c;请放心使用。此篇文章是上篇文章解决vs2019中暂时无法为.net core WinForms使用 Designer 的临时方法的姊妹篇&#xff0c;但对WPF而言实现起来比WinForms简单很多…

Building Fire Stations

题目链接 首先找到树的直径&#xff0c;直径左端点是a&#xff0c;直径右端点是b&#xff0c;中间的点是mid&#xff08;偶数的情况下mid可以看做两个&#xff09;&#xff0c;两点因该是左右分布&#xff1b; 假设两点都不在直径上&#xff0c;那么移到直径上的话距离更短&a…

.NET Core 迁移躺坑记

最近将自己负责的一个核心接口系统从.Net Framework迁移到了.Net Core。整体过程&#xff0c;从业务层面说一般般吧(整体还好但还是搞的业务有感&#xff0c;没出严重故障&#xff09;但是技术层面上感觉其实并没有达到要求&#xff0c;不过预期也是应该不会那么顺利&#xff0…