簡體   English   中英

將傳統的異步處理程序包裝到TPL Task時 <T> 回調和狀態會如何?

[英]When wrapping traditional asynchronous handlers to TPL Task<T> what happens to the Callback and State?

此MSDN頁面包含以下示例 :目的是包裝一個不能在各種Func<T1, T2, T3>重載中表示的APM樣式任務。

static Task<String> ReturnTaskFromAsyncResult()
{
    IAsyncResult ar = DoSomethingAsynchronously();     // <-- If this is an APM method, it's a bad example since most APM methods have a parameter for callback and state.
    Task<String> t = Task<string>.Factory.FromAsync(ar, _ =>
        {
            return (string)ar.AsyncState;
        });

    return t;
}

我的問題與函數DoSomethingAsynchronously(); 我見過的大多數APM函數都需要參數callback和state,此示例中沒有此參數。

問題: “ DoSomethingAsynchronously”中的回調和狀態參數會怎樣?

我需要怎么做才能正確調用類似於此的函數? 就我而言,我試圖像這樣包裝Azure Table調用

    Task CreateAsync(CloudTable tbl, CancellationToken token, object state)
    {
        ICancellableAsyncResult result = tbl.BeginCreate(null, state);  // Incorrect
        token.Register((o) => result.Cancel(), state);

        Task<bool> t = Task.Factory.FromAsync(result, _ =>
        {
            return (bool)result.AsyncState;
        });

        return t;
    }
    Task<bool> ExistsAsync(CloudTable tbl, CancellationToken token, object state)
    {
        ICancellableAsyncResult result = tbl.BeginExists(null, state);  // Incorrect
        token.Register((o) => result.Cancel(), state);

        Task<bool>  t = Task.Factory.FromAsync(result, _ =>
        {
            return (bool)result.AsyncState;
        });

        return t;
    }

我認為您誤解了state參數的用途。 它在那里供您使用 :當您在其中傳遞對象時,可以通過訪問AsyncState檢索它。 (並且類似地在CancellationToken.Register() state 。)在這種情況下,您不需要任何state ,因此您應該在其中傳遞null 這也意味着您沒有理由要創建的方法具有state參數。

callback參數用於異步操作完成時要執行的代碼。 您不需要的FromAsync()重載不使用此方法,因此您也應該在其中傳遞null

似乎您也對放在endMethod委托中的內容感到困惑。 顧名思義,您應該在其中調用EndXxx()方法(在您的情況下為EndCreate()EndExists() )。 如果整個操作都返回了某些內容,則它實際上將由end方法返回,因此您應該從委托中返回它。 然后,它將作為創建的Task的結果可用。 您還可以在委托中執行一些清理。 在您的情況下,我認為將取消注冊在那里處置是有意義的,因為不再需要取消注冊。

因此,您的代碼應類似於:

Task CreateAsync(CloudTable tbl, CancellationToken token)
{
    ICancellableAsyncResult result = tbl.BeginCreate(null, null);
    var cancellationRegistration = token.Register(result.Cancel);

    return Task.Factory.FromAsync(result, ar =>
    {
        cancellationRegistration.Dispose();
        tbl.EndCreate(ar);
    });
}

Task<bool> ExistsAsync(CloudTable tbl, CancellationToken token)
{
    ICancellableAsyncResult result = tbl.BeginExists(null, null);
    var cancellationRegistration = token.Register(result.Cancel);

    return Task.Factory.FromAsync(result, ar =>
    {
        cancellationRegistration.Dispose();
        return tbl.EndExists(ar);
    });
}

有關此主題的更多信息,請查看Stephen Toub的“ 任務”和“ APM模式”

暫無
暫無

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

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