【问题标题】:how to forget synchronization context in async methods in c#如何在 c# 的异步方法中忘记同步上下文
【发布时间】:2013-05-30 04:19:24
【问题描述】:

假设我要编写一个异步方法 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 中的所有任务都已完成并且所有内容都可以在同一个线程上同步运行而无需上下文切换的情况下。有没有更好的解决方案来忘记线程的同步上下文?还是我错过了什么,这会使这个问题变得无关紧要?

【问题讨论】:

    标签: c# asynchronous synchronizationcontext


    【解决方案1】:

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

    create a synchronous wrapper for an asynchronous method 没有简单的方法。最好让异步方法异步。

    可以使用ConfigureAwait(continueOnCapturedContext: false) 丢弃上下文,但在您的情况下它不会比Task.Run 更好,因为您无法更改M 调用的方法。

    【讨论】:

    • +1 获取精彩链接!构建框架的人必读
    猜你喜欢
    • 1970-01-01
    • 2013-09-01
    • 2020-12-04
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多