[英]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.