所以我知道我通常应该在库代码中使用 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)方法的同一上下文中返回?根据类似用例做出决定,例如 WebClient
的 DownloadDataCompleted
,调用 DownloadDataAsync
时引发的事件。做出决定后,清楚地记录下来并确保您遵守该规范。
一般来说,我会选择不在原始上下文中调用事件的选项。如果调用者想要编码返回,它总是可以这样做。但是,如果不需要,您将强制整个 async
链在每次从异步调用返回时都为原始上下文而战,但无济于事。尽可能与上下文无关,并在最后可能的时刻返回。
当然,您可以问问自己是否需要一个事件和一个返回任务的方法,它们都发出完全相同的异步事件信号。监听 WebHookTriggered
事件的客户端是否与调用公共(public)异步方法的代码相同?
关于c# - ConfigureAwait(false) 和库代码中的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54906004/