c# - ConfigureAwait(false) 和库代码中的事件

标签 c# asynchronous async-await

所以我知道我通常应该在库代码中使用 ConfigureAwait(false)。异常(exception)是当我知道继续将需要调用者上下文时。 但是,如果我不知道会是这样的话,我不知道该怎么办。我猜我不应该在这种情况下使用 ConfigureAwait(false) - 但我想确认这一点。

示例:我的类(class)事件很少:

public static event TriggeredWebhookInfo WebhookTriggered;
public static event ReadonlyWebhookInfo WebhookCancelled;

还有一个方法(它是 private,因为它由 public Task 返回方法调用,但它也使用 ConfigureAwait(false)) :

private static async Task<HttpResponseMessage> TriggerTaskAsync(string url, WebhookBody body)
{
    if (body == null || url == null)
    {
        WebhookCancelled?.Invoke(url, body);
        Logger.Write(InternalTag.Sender, "Webhook cancelled: " + url, LogType.Normal);
        return null;
    }
    HttpResponseMessage response = await Client.PostAsync(url, GetContent(body)).ConfigureAwait(false);
    WebhookTriggered?.Invoke(url, body, response);
    Logger.Write(InternalTag.Sender, "Webhook triggered: " + url, LogType.Normal);
    return response;
}

现在,当然这对任何终端应用程序都完全适用。但是,如果事件在非终端应用程序中调用用户分配的 UI 上下文上的方法,会发生什么情况? Invoke() 会缓解任何问题,还是我应该从调用堆栈中删除 ConfigureAwait(false) 到此方法?

最佳答案

您必须进行设计调用 - 事件是否保证在调用公共(public)方法的同一上下文中返回?根据类似用例做出决定,例如 WebClientDownloadDataCompleted,调用 DownloadDataAsync 时引发的事件。做出决定后,清楚地记录下来并确保您遵守该规范。

一般来说,我会选择在原始上下文中调用事件的选项。如果调用者想要编码返回,它总是可以这样做。但是,如果不需要,您将强制整个 async 链在每次从异步调用返回时都为原始上下文而战,但无济于事。尽可能与上下文无关,并在最后可能的时刻返回。

当然,您可以问问自己是否需要一个事件和一个返回任务的方法,它们都发出完全相同的异步事件信号。监听 WebHookTriggered 事件的客户端是否与调用公共(public)异步方法的代码相同?

关于c# - ConfigureAwait(false) 和库代码中的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54906004/

相关文章:

c# - log4net 和每个线程唯一的日志文件

c# - 英孚。在没有 [Required] 属性的情况下引发字符串字段的必需验证错误

Javascript异步等待不等待 Mongoose 等待

c# - Windows 域登录可以包含超过 1 个 '\' 字符吗?

c# - Visual Studio : When and why a class file name change will automatically update references to that class

unit-testing - 如何对调用异步方法的同步方法进行单元测试?

asynchronous - 如何以及何时在 Julia 中使用 @async 和 @sync

android - ListActivity 的异步更新

c# - 是否可以将异步方法作为 c# 中事件处理程序的回调?

node.js - Nodejs - 异步/等待我的 Controller