c# - Task.Run 中的异步 lambda 与常规 lambda
问题描述
假设我有一个方法可以运行带有一些异步调用的连续 while 循环
async Task MethodA(){
while(true){ perform async/await operations }
}
有什么区别:
Task.Run( () => MethodA(); }
Task.Run( async () => await MethodA(); }
如果有区别,什么时候比另一个更有用?
解决方案
根据 Stephen Cleary 在回答https://stackoverflow.com/a/19098209/3107892和他的链接博客文章中的回答,唯一的区别是第二个创建状态机。在这里,您可以使用第一种情况而没有任何缺点。
以下是您可以遵循的一些准则:
- 默认情况下不要省略。使用 async 和 await 获得自然、易读的代码;
- 当方法只是传递或重载时,请考虑省略;
- 如果您希望该方法显示在您的堆栈跟踪中,请不要省略。
只是为了完整,基于此处的另一个答案:
Task.Run(Func<Task>)
将在线程池中排队函数的结果,并且结果函数将在排队的任务完成时完成(包括所有等待)
Task.Run( MethodA );
将方法转换为委托并传递它。
Task.Run( () => MethodA() );
将创建一个隐藏方法,该方法将返回结果MethodA
(正是这个隐藏方法将被转换为委托并传递)。
Task.Run( async () => await MethodA() );
将创建一个包含 await 的隐藏方法,但如前所述,这将转换为状态机,最终将结果包装MethodA()
在一个新的Task
.
Task.Run( () => { MethodA(); } );
是完全不同的东西,因为大括号,这将调用Task.Run(Action)
重载,在这种情况下,MethodA()
它将在这个任务上运行,直到它遇到第一个未完成的等待然后完成。在这个内部任务完成之后(内部等待之后)发生的事情不会被它监控,Task.Run
但会继续在线程池上运行,如果它抛出异常,可能会导致你的应用程序崩溃。原因是MethodA
返回的任务由于缺少关键字而被忽略return
。
Task.Run( () => { return MethodA(); } );
是此异常的修复程序,并且将与所有其他示例一样工作。
推荐阅读
- c# - 在实体框架中保存数据+关系数据的最佳/最简单方法
- javascript - 使用 jquery 的一页滚动网站
- jackson - 是否可以将请求 json 主体的 RFC3339 完整日期字段反序列化为 msf4j 应用程序中的某个 java 日期类?
- git - 创建 CI/CD heroku 、 git 和 jenkins
- amazon-web-services - dynamodb 是否适合成长型或可旋转的产品?
- python - 使用请求 HTML 找不到 css 类
- python - Django 对象 order_by 给我重复的用户
- rest - Golang REST API 项目结构
- javascript - 在某些特定网站上更改 chrome 扩展程序的图标
- reactjs - 如何使用物化和 scss 防止 @media 查询错误