我想執行一個重試任務,該任務採用先前的失敗任務操作並重復執行。重試以前的任務動作TPL
這是我到目前爲止。然而,它只是重複了任務錯誤而不是實際再次開始任務動作的事實。
public static async Task<T> Retry<T>(this Task<T> task, int retryCount, int delay, TaskCompletionSource<T> tcs = null)
{
if (tcs == null)
{
tcs = new TaskCompletionSource<T>();
}
await task.ContinueWith(async _original =>
{
if (_original.IsFaulted)
{
if (retryCount == 0)
{
tcs.SetException(_original.Exception.InnerExceptions);
}
else
{
Console.WriteLine("Unhandled exception. Retrying...");
await Task.Delay(delay).ContinueWith(async t =>
{
await Retry(task, retryCount - 1, delay, tcs);
});
}
}
else
tcs.SetResult(_original.Result);
});
return await tcs.Task;
}
我試圖用一點反思來得到這個動作。但是,似乎一旦任務完成,操作就會設置爲空。
var action = task
.GetType()
.GetField("m_action", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(task) as Action;
理想情況下,我想我的實現看起來像這樣:
try
{
await MakeFailure().Retry(5, 1000);
}
catch (Exception ex)
{
Console.WriteLine("I had an exception");
}
這是不可能的,但我想的代碼重構到Retry(Func<T> task)
你對抗不使這是一個擴展方法,改變方法簽名爲'靜態異步任務重試(Func鍵> taskFactory,INT RetryCount重,...'? –
不完全反對這麼做,但是它改變了代碼流向錯誤第一個佈局,我不喜歡'''Retry(async()=> await MakeFailure(),5,1000)'''不像'''等待MakeFailure()乾淨。 Retry(5,1000)''' –
不要試圖破解TPL來做一些不適合的事情。在它上面創建一個抽象。 – i3arnon