如何忘记 C# 中异步方法中的同步上下文

2024-03-10

假设我想编写一个异步方法M。我不知道将使用什么样的同步上下文(UI、ASP.NET、控制台应用程序等)来调用它。我想让该方法尽可能易于使用。这意味着任何人都应该能够通过访问返回的任务的 Result 成员来同步调用它。

public async Task<int> M()
{
    // lot's of calling of helper methods including awaits, etc.
    // helper methods not owned by me
    // ...

    return 42;
}


// this should be safe to do from any synchronization context
int result = M().Result; // Synchronously wait

问题是方法 M 的调用者的同步上下文被泄漏给 M 的被调用者。如果其中任何一个想要继续传入同步上下文,那么它可能会死锁(例如,当使用 UI 同步上下文时)。

调用 M 时忘记同步上下文的一种解决方案是将 M 的内容包装在 Task.Run 中。但是,这将强制线程跳转,包括 M 内的所有任务都已完成并且所有内容都可以在同一线程上同步运行而无需上下文切换的情况。有没有更好的解决方案来忘记线程的同步上下文?或者我错过了什么,这会让这个问题变得无关紧要?


我想让该方法尽可能易于使用。这意味着任何人都应该能够通过访问返回的任务的 Result 成员来同步调用它。

没有简单的方法为异步方法创建同步包装器 http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx。最好让异步方法异步。

You can use ConfigureAwait(continueOnCapturedContext: false)放弃上下文,但它不会比Task.Run在你的情况下,因为你无法改变方法M calls.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何忘记 C# 中异步方法中的同步上下文 的相关文章