异步库最佳实践:ConfigureAwait(假)与设置同步上下文 [英] Async library best practice: ConfigureAwait(false) vs. setting the synchronization context

查看:403
本文介绍了异步库最佳实践:ConfigureAwait(假)与设置同步上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是众所周知的,在一个通用库, ConfigureAwait(假)应在每次使用伺机打电话,以避免继续对当前的SynchronizationContext。

It's well-known that in a general-purpose library, ConfigureAwait(false) should be used on every await call to avoid continuing on the current SynchronizationContext.

作为替代与 ConfigureAwait(假),可以简单地设置的SynchronizationContext为null一次,公众面法,并返回给用户之前将其还原。换句话说:

As an alternative to peppering the entire codebase with ConfigureAwait(false), one could simply set the SynchronizationContext to null once, at the public surface method, and restore it before returning to the user. In other words:

public async Task SomeSurfaceMethod()
{
    var callerSyncCtx = SynchronizationContext.Current;
    SynchronizationContext.SetSynchronizationContext(null);
    try
    {
        // Do work
    }
    finally
    {
        SynchronizationContext.SetSynchronizationContext(callerSyncCtx);
    }
}

这也可以被包裹在一个使用为更好的可读性。

This could also be wrapped in a using for better readability.

有没有这种方法有一个缺点,它不能最终产生同样的效果?

Is there a disadvantage to this approach, does it not end up producing the same effect?

的主要优点是明显的可读性 - 全部拆除 ConfigureAwait(假)电话。它也可以减少遗忘一个 ConfigureAwait(假)某处的可能性(尽管分析仪缓和这一点,可以认为,开发人员也可以同样忘记改变的SynchronizationContext)。

The major advantage is obviously readability - the removal of all ConfigureAwait(false) calls. It may also reduce the likelihood of forgetting a ConfigureAwait(false) somewhere (although analyzers mitigate this, and it could be argued that developers could just as well forget changing the SynchronizationContext).

一个有些奇特的优势并不嵌入捕获的SynchronizationContext或者不所有方法的选择。换句话说,在一个情况下,我可能想用的SynchronizationContext运行方法X,而在另一个我可能要无一运行相同的方法。当 ConfigureAwait(假)嵌入无处不那是不可能的。当然,这是一个相当罕见的要求,但我碰到了它,而在Npgsql工作(触发了这个问题)。

A somewhat exotic advantage is not embedding the choice of capturing the SynchronizationContext or not in all methods. In other words, in one case I may want to run method X with a SynchronizationContext, while in another I may want to run the same method without one. When ConfigureAwait(false) is embedded everywhere that isn't possible. Granted, this is quite a rare requirement, but I bumped into it while working on Npgsql (triggering this question).

推荐答案

由于@MrinalKamboj在评论中写道,的的SynchronizationContext在公众面法暂时设置为null,设置回该方法已经提出的此处。似乎没有要与此相关的任何具体问题(见这里斯蒂芬·克利里的回答)。

As @MrinalKamboj wrote in the comments, the approach of temporarily setting the SynchronizationContext to null at the public surface method and setting back has already been proposed here. There doesn't seem to be any specific problem associated with this (see Stephen Cleary's answer here).

这篇关于异步库最佳实践:ConfigureAwait(假)与设置同步上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆