[英]Convert Task to Task<T> (Wrap Task with return type of T)
我已經閱讀了這個問題,但就我而言,它比較簡單,因為我不必使用Result
屬性。 所以我想知道是否可以采用比Stephen Cleary的答案所提供的方法更簡單的方法。
假設我有這個簡單的界面。
internal interface IBinaryDataReadable
{
Task Load(AsyncDataReader reader);
}
該接口提供了異步加載對象的方法。 它不會返回任何內容,因為加載結果是對象本身。
(該接口是內部的,因此明確地實現了該接口以避免公開實現。)
這是我加載二進制數據的方式。
data = new BinaryData();
await ((IBinaryDataReadable)data).Load(reader);
我想讓它更流暢和冗長,所以我寫了這個擴展方法
internal static Task<TData> Load<TData>(this TData data, AsyncDataReader reader)
where TData : IBinaryDataReadable
=> data.Load(reader).ContinueWith(t => data, TaskContinuationOptions.ExecuteSynchronously);
現在加載變得像這樣。
data = await new BinaryData().Load(reader);
這里是否有我需要擔心使用此方法的問題?例如異常處理等?
可以使用async / await完成此操作,並使用ContinueWith
放棄
internal static async Task<TData> Load<TData>(this TData data, AsyncDataReader reader)
where TData : IBinaryDataReadable {
await data.Load(reader);
return data;
}
這樣,如果需要,您甚至可以在方法中包括異常處理。 但是,擴展方法在流暢的界面方面做不到很多,因為該方法返回需要等待的Task。
而且,您將必須顯式地調用通用擴展名,否則,您將僅調用該類型的本地成員,該類型將在等待導致編譯錯誤時解析為void
。
data = await new BinaryData().Load<BinaryData>(reader);
我建議將擴展方法重命名為不會與接口上現有成員沖突的擴展方法。
data = await new BinaryData().LoadAsync(reader);
我想知道使用
ContinueWith
是否會帶來問題
我看不到它不會帶來任何問題,除非無法確保異常。 但這可以通過檢查這種情況並冒泡進行管理。
internal static Task<TData> LoadAsync<TData>(this TData data, AsyncDataReader reader)
where TData : IBinaryDataReadable {
return data.Load(reader)
.ContinueWith(t => {
var error = t.Exception;
if (error != null && t.IsFaulted)
throw error;
return data;
}, TaskContinuationOptions.ExecuteSynchronously);
}
雖然在我看來,使用async / await更加整潔,更易於閱讀和實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.