簡體   English   中英

庫代碼中的ConfigureAwait(false)和事件

[英]ConfigureAwait(false) and events in library code

因此,我知道通常應該在庫代碼中使用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)

如果要允許方法處理程序具有與調用方相同的上下文,則需要刪除ConfigureAwait(false) 也就是說,您可以采用任何一種方式進行操作; 重要的是記錄消費者的期望。

另外,您可以使用IObservable<T>發布事件,但這要復雜得多,並且會帶來另一個(非平凡的)依賴關系。

您必須進行設計調用-是否保證事件在調用public方法的同一上下文中返回? 您的決定基於類似的用例,例如WebClientDownloadDataCompleted ,該事件在調用DownloadDataAsync時引發。 一旦決定,請清楚地記錄下來並確保您遵守該規范。

一般來說,我會選擇不在原始上下文中調用事件的選項。 如果呼叫者想將其封送,則始終可以這樣做。 但是,如果不需要,您將迫使整個async鏈在每次從異步調用返回時為原始contxt爭用,一無所有。 盡可能保持不受上下文限制,並在最后可能的時刻調頭。

當然,您可以問自己是否同時需要一個事件和一個任務返回方法,它們都發出完全相同的異步事件。 客戶端偵聽WebHookTriggered事件是否與調用公共異步方法的代碼相同?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM