在.NetFramework中,使用以下方法同步到同步上下文时,很有可能发生死锁:
this.props.navigation.navigate(userToken ? 'App' : 'Auth');
代替
var result = asyncMethod().Result;
var result = asyncMethod().GetAwaiter().GetResult();
(read Stephen Cleary blogpost for more info)
由于同步上下文已在.NetCore中删除。这是否意味着上述方法现在可以安全使用?
答案 0 :(得分:3)
是,不是。确实,.NET Core中没有同步上下文,因此,消除了死锁问题的主要来源之一。但是,这并不意味着完全不可能发生死锁。无论如何,您不应因为良好的编程习惯而滑倒,只是因为在某种情况下它可能不再是一个大问题。特别是ASP.NET Core,它是完全异步的,因此没有理由使用方法的同步版本或仅阻塞异步任务。像往常一样应该使用await
。
答案 1 :(得分:2)
您可以阻止异步代码-但您不应该
第一个也是最明显的结果是,等待未捕获任何上下文。这意味着阻塞异步代码不会导致死锁。您可以使用Task.GetAwaiter()。GetResult()(或Task.Wait或Task.Result)而不必担心死锁。 但是,您不应该。因为阻塞异步代码的那一刻,您就首先放弃了异步代码的所有好处。阻塞线程后,异步处理程序增强的可伸缩性将被取消。 在(传统)ASP.NET中有两种情况,不幸的是必须进行阻止:ASP.NET MVC筛选器和子操作。但是,在ASP.NET Core中,整个管道是完全异步的。筛选器和视图组件均异步执行。 总之,理想情况下,您应该努力一直使用异步;但是如果您的代码需要,它可以毫无危险地阻塞。
-Extract from blogpost by Stephen Cleary
贷记GSerg来查找帖子
但是,您可能会遇到线程池不足
http://labs.criteo.com/2018/10/net-threadpool-starvation-and-how-queuing-makes-it-worse/