防止异步 .NET 操作中的死锁:解决 Result
属性问题
.NET 的 async
和 await
关键字显着改进了异步编程。但是,访问 Result
的 Task
属性可能会导致令人沮丧的应用程序挂起。 本文解释了原因并提供了解决方案。
核心问题源于任务运行时的默认行为:它安排异步函数在其开始处的同一个 SynchronizationContext
上继续执行。 例如,如果异步方法在 UI 线程上运行,则其延续(“返回结果;”)也会在 UI 线程上运行。
当 UI 线程在 Task.Result
上阻塞而 Task
不完整时,就会发生死锁。运行时尝试在阻塞的 UI 线程上执行延续,从而创建循环依赖:在执行 return 语句之前无法检索 Result
,但在 UI 线程解除阻塞之前,无法执行 return 语句。
防止死锁的策略:
1。一致的await
用法:
最简单的解决方案是在整个代码中一致使用 await
。这可确保在 Task
的延续中正确安排所有操作。
2。删除 async
修饰符(如适用):
如果使用 await
不切实际,请从直接调用底层代码的简单任务返回方法中删除 async
修饰符。 避免“返回结果”;这些情况下的模式。
3。雇用ConfigureAwait(false)
:
要显式控制连续调度,请使用 ConfigureAwait(false)
。这会强制继续在线程池线程上运行,而不管当前的SynchronizationContext
。这可以确保延续永远不会在阻塞的线程上运行,从而防止死锁。
以上是在 .NET 中访问异步任务的'Result”属性时如何防止死锁?的详细内容。更多信息请关注PHP中文网其他相关文章!