因此,我知道我通常应该在库代码中使用ConfigureAwait(false)
。例外是当我知道继续将需要调用者上下文时。
但是,如果我不知道会发生这种情况,我不知道该怎么办。我猜我在这种情况下不应该使用ConfigureAwait(false)
-但是我想确认一下。
示例:我的班级很少发生以下事件:
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)
?
答案 0 :(得分:2)
如果要允许方法处理程序具有与调用方相同的上下文,则需要删除ConfigureAwait(false)
。也就是说,您可以采用任何一种方式进行操作;重要的是记录您的消费者应该期望的东西。
或者,您可以使用IObservable<T>
发布事件,但这要复杂得多,并且会带来另一个(非常重要的)依赖项。
答案 1 :(得分:1)
您必须进行设计调用-是否保证事件在调用公共方法的相同上下文上返回?您的决定基于类似的用例,例如WebClient
的{{1}},这是在调用DownloadDataCompleted
时引发的事件。确定后,明确记录并确保您遵守该规范。
一般来说,我会选择不在原始上下文中调用事件的选项。如果呼叫者想将其封送,则始终可以这样做。但是,如果不需要,您将迫使整个DownloadDataAsync
链为每次从异步调用返回时的原始contxt争用,一无所有。尽可能保持不受上下文限制,并在可能的最后时刻调回军队。
当然,您可以问自己是否同时需要一个信号和一个返回任务的方法,这两个信号都表示完全相同的异步事件。客户端在监听async
事件时是否使用与调用公共异步方法相同的代码?