前几天在用线程池执行一些任务时运到一种情形,就是回调方法中使用到了异步方法,但是回调方法貌似不支持async await的写法。这时候我应该如何处理呢?是使用Task.Result来获取返回结果,还是使用GetAwaiter.GetResult()呢?本文就来探讨下吧。

作者:依乐祝

原文地址:https://www.cnblogs.com/yilezhu/p/13168337.html

这里先上我这种场景的伪代码:

ThreadPool.QueueUserWorkItem(ExcuteScanProcess, node);

ExcuteScanProcess这个回调方法中

private void ExcuteScanProcess(object state)
{
……其他处理……
repository.UpdateAsync(node).ConfigureAwait(false).GetAwaiter().GetResult();
……其他处理……
}

如上图所示repository.UpdateAsync(node)属于一部方法,这时候我想要等待它异步执行完成之后再执行后续的逻辑。这时候我有两种选择,是直接

repository.UpdateAsync(node).ConfigureAwait(false).GetAwaiter().GetResult();

好呢,还是

repository.UpdateAsync(node).ConfigureAwait(false).Result;

好呢?

为此我查找了相关的资料,对它俩的区别做一个简单的总结:

其实这两个使用方式是差不多的。不过,还是有一点小小的区别的:如果任务失败,Task.GetAwaiter().GetResult()会直接抛出异常,而Task.Result则会把异常包装在AggregateException中。从这个角度说Task.GetAwaiter().GetResult()要优于Task.Result。毕竟它少了异常的包装操作,即直接抛出异常,而不是把异常包装在AggregateException中。

下面的引言解释了为什么Task.Result不仅仅包含Task.GetAwaiter().GetResult()(由于“非常高的兼容性”)的异常传播行为。

如前所述,我们有一个非常高的兼容性标准,因此我们避免了改动。因此,Task.Wait保留了始终包装的原始行为。但是,您可能会发现自己处在某些高级情况下,这些情况下您想要的行为类似于所采用的同步阻塞Task.Wait,但是您希望将原始异常展开而不是传播,而不是将其封装在AggregateException中。为此,您可以直接定位任务的等待者。当您编写“ await task;”时,编译器Task.GetAwaiter()会将其转换为方法的用法,这将返回具有GetResult()方法的实例。当用于有故障的任务时,GetResult()将传播原始异常(这是“ await task;” 如何获得其行为)。因此,您可以使用“task.GetAwaiter().GetResult()如果您想直接调用此传播逻辑。

https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/

GetResult”实际上表示“检查任务是否有错误”

通常,我会尽力避免对异步任务进行同步阻塞。但是,在少数情况下,我确实违反了该准则。在那些罕见的情况下,我的首选方法是GetAwaiter().GetResult()因为它保留任务异常,而不是将它们包装在中AggregateException

总结

通过上述内容的阐述,因此在那些必须对异步任务进行同步阻塞的场景中,我选择使用GetAwaiter().GetResult()

Task.Result跟 Task.GetAwaiter.GetResult()相同吗?怎么选?的更多相关文章

  1. 初步学习async/await,Task.GetAwaiter,Task.Result

    网上关于async/await的知识有很多,看了很多但不如自己实践一遍来得快,所以这里记录下我的理解和大家学习下. 首先以最简单的同步方法来开始如下 private static void Test( ...

  2. .net core Task.Result Wait等造成502

    这两天公众号项目上线,刚开始项目运行没什么问题,但几天之后,访问量激增,服务器崩溃了,每次请求都返回502,一脸懵逼,无从下手,赶紧开日志里的BUG,拿出来一个个改,BUG都改完之后,没有明显的效果, ...

  3. Parallel Programming-Task Result && Continuation Task

    本文主要介绍带有返回值的Task和Continuation Task 带返回值的Task Continuation Task ContinueWhenAll即多任务延续 一.带返回值的Task 1.1 ...

  4. async await task.Result 卡死

    在如下代码中: public async Task<string> GetData() { return await DoWork(); } 在UI线程中调用 var data = Get ...

  5. async,await与task.wait()或task.Result的区别

    你是否曾经与我一样不理解async,await与task.wait()或者task.Result的区别? 接下来,一个Demo让你看出他们之间的区别. static void Main(string[ ...

  6. 一句 Task.Result 就死锁, 这代码还怎么写?

    一:背景 1. 讲故事 前些天把 .NET 高级调试 方面的文章索引到 github 的过程中,发现了一个有意思的评论,详见 文章,截图如下: 大概就是说在 Winform 的主线程下执行 Task. ...

  7. 【C# Task】理解Task中的ConfigureAwait配置同步上下文

    原文:https://devblogs.microsoft.com/dotnet/configureawait-faq/ 作者:Stephen 翻译:xiaoxiaotank 静下心来,你一定会有收获 ...

  8. Task.Run与Task.Factory.StartNew的区别

    Task是可能有延迟的工作单元,目的是生成一个结果值,或产生想要的效果.任务和线程的区别是:任务代表需要执行的作业,而线程代表做这个作业的工作者. 在.Net 4中,Task.Factory.Star ...

  9. Task.Run Vs Task.Factory.StartNew

    在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ...

随机推荐

  1. SqlServer2008查询性能优化_第一章

  2. Map.Entry的作用

    一般情况下,要输出Map中的key 和 value 是先得到key的集合,然后再迭代(循环)由每个key得到每个value 而Entry可以一次性获得这两个值 Set set = map.keySet ...

  3. Java IO(十四) CharArrayReader 和 CharArrayWriter

    Java IO(十四) CharArrayReader 和 CharArrayWriter 一.介绍 CharArrayReader 和 CharArrayWriter 是字符数组输入流和字符数组输出 ...

  4. 05 . Nginx的反向代理与负载均衡

    Nginx负载均衡 客户端的访问都被代理到后端的一台服务器上,最终会出现性能瓶颈,从而导致效率降低,前端用户的访问速度急速下降,要解决这个问题就需要添加多台httpd,同时承受大量并发连接,每台服务器 ...

  5. 小谢第2问:后端返回为数组list时候,怎么实现转为tree

    要求后端返回给我的list时候,在数组中定义有id , parentid, 可以用双重循环的方法,得到tree需要的数据结构,这样得到的数据就可以直接复制给树组件的data啦const oldData ...

  6. Beta冲刺——5.25

    这个作业属于哪个课程 软件工程 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.会议内容 1.解决小程序之前的遗留问题 ...

  7. jchdl - RTL实例 - Adder4Carry

    https://mp.weixin.qq.com/s/j4zLmjKgau2vRXVNfm0SIA   带进位的加法.   参考链接 https://github.com/wjcdx/jchdl/bl ...

  8. Java实现 LeetCode 821 字符的最短距离(暴力)

    821. 字符的最短距离 给定一个字符串 S 和一个字符 C.返回一个代表字符串 S 中每个字符到字符串 S 中的字符 C 的最短距离的数组. 示例 1: 输入: S = "loveleet ...

  9. Java实现 LeetCode 773 滑动谜题(BFS)

    773. 滑动谜题 在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示. 一次移动定义为选择 0 与一个相邻的数字(上下左右)进行交换. 最终 ...

  10. Java实现 LeetCode 667 优美的排列 II(暴力)

    667. 优美的排列 II 给定两个整数 n 和 k,你需要实现一个数组,这个数组包含从 1 到 n 的 n 个不同整数,同时满足以下条件: ① 如果这个数组是 [a1, a2, a3, - , an ...