Task.Result跟 Task.GetAwaiter.GetResult()相同吗?怎么选?
前几天在用线程池执行一些任务时运到一种情形,就是回调方法中使用到了异步方法,但是回调方法貌似不支持async await的写法。这时候我应该如何处理呢?是使用Task.Result来获取返回结果,还是使用GetAwaiter.GetResult()呢?本文就来探讨下吧。
作者:依乐祝
这里先上我这种场景的伪代码:
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()相同吗?怎么选?的更多相关文章
- 初步学习async/await,Task.GetAwaiter,Task.Result
网上关于async/await的知识有很多,看了很多但不如自己实践一遍来得快,所以这里记录下我的理解和大家学习下. 首先以最简单的同步方法来开始如下 private static void Test( ...
- .net core Task.Result Wait等造成502
这两天公众号项目上线,刚开始项目运行没什么问题,但几天之后,访问量激增,服务器崩溃了,每次请求都返回502,一脸懵逼,无从下手,赶紧开日志里的BUG,拿出来一个个改,BUG都改完之后,没有明显的效果, ...
- Parallel Programming-Task Result && Continuation Task
本文主要介绍带有返回值的Task和Continuation Task 带返回值的Task Continuation Task ContinueWhenAll即多任务延续 一.带返回值的Task 1.1 ...
- async await task.Result 卡死
在如下代码中: public async Task<string> GetData() { return await DoWork(); } 在UI线程中调用 var data = Get ...
- async,await与task.wait()或task.Result的区别
你是否曾经与我一样不理解async,await与task.wait()或者task.Result的区别? 接下来,一个Demo让你看出他们之间的区别. static void Main(string[ ...
- 一句 Task.Result 就死锁, 这代码还怎么写?
一:背景 1. 讲故事 前些天把 .NET 高级调试 方面的文章索引到 github 的过程中,发现了一个有意思的评论,详见 文章,截图如下: 大概就是说在 Winform 的主线程下执行 Task. ...
- 【C# Task】理解Task中的ConfigureAwait配置同步上下文
原文:https://devblogs.microsoft.com/dotnet/configureawait-faq/ 作者:Stephen 翻译:xiaoxiaotank 静下心来,你一定会有收获 ...
- Task.Run与Task.Factory.StartNew的区别
Task是可能有延迟的工作单元,目的是生成一个结果值,或产生想要的效果.任务和线程的区别是:任务代表需要执行的作业,而线程代表做这个作业的工作者. 在.Net 4中,Task.Factory.Star ...
- Task.Run Vs Task.Factory.StartNew
在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ...
随机推荐
- 将`VuePress`建立的博客部署到GitHub或Gitee上
将VuePress建立的博客部署到GitHub或Gitee上 在上一篇中,我们详细介绍了如何利用VuePress搭建起个人博客系统,但这只是在本地debug启动的,接下来,我们把它部署到Github网 ...
- Condition线程通信_生产者消费者案例
①Condition 接口描述了可能会与锁有关联的条件变量. 这些变量在用 法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的 功能. 需要特别指出的是,单个 Lock 可能与 ...
- CVE-2016-3714-ImageMagick 漏洞利用
漏洞简介:/etc/ImageMagick/delegates.xml 将%s,%l加入到command里造成了命令执行 利用方式: poc代码: push graphic-context viewb ...
- 移动端适配-rem(新)
概念 对于移动端开发来说,无可避免的就是直面各种设备不同分辨率和不同DPR(设备像素比)的问题,在此忽略其他兼容性问题的探讨. 移动端像素 设备像素(dp),也叫物理像素.指设备能控制显示的最小物理单 ...
- 2019-ICCV-PDARTS-Progressive Differentiable Architecture Search Bridging the Depth Gap Between Search and Evaluation-论文阅读
P-DARTS 2019-ICCV-Progressive Differentiable Architecture Search Bridging the Depth Gap Between Sear ...
- 「MoreThanJava」一文了解二进制和CPU工作原理
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- MethodHandle(方法句柄)系列之三:invoke和invokeExact的区别
先把代码贴上来,用的是一样的代码 /** * * @author LiuYeFeng<897908343@qq.com> * @date 2015年4月8日 下午10:41:13 * @C ...
- 细说Java多线程之内存可见性笔记
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 说明:多线程的内存可见性涉及到多线程间的数据争用,也涉及到了多线程间的数据可见性 一.共享变量在线程间的 ...
- 【Mysql】使用一条sql查询出库表结构信息
1.新建查询 将以下脚本粘贴进去 脚本如下: SELECT TABLE_SCHEMA 库名, TABLE_NAME 表名, COLUMN_NAME 列名, COLUMN_TYPE 数据类型, DATA ...
- 【Spring注解驱动开发】聊聊Spring注解驱动开发那些事儿!
写在前面 今天,面了一个工作5年的小伙伴,面试结果不理想啊!也不是我说,工作5年了,问多线程的知识:就只知道继承Thread类和实现Runnable接口!问Java集合,竟然说HashMap是线程安全 ...