我有一個通用方法,用于在同步背景關系中執行異步任務并重試。
public static T RunWithRetries<T>(Task<T> task)
{
while(...) // 3 attempts
{
try
{
task.GetAwaiter().GetResult();
}
catch
{
// sleep & retry later in case of some exceptions, for example 429
}
}
}
然后我從異步 API 傳遞任何方法來像這樣運行它。
SyncHelper.RunWithRetries(externalAPI.UploadAsync(fileRequest, fileStream));
問題是它可以作業,除非在請求期間發生例外并且我們需要重試。如果發生錯誤,所有后續重試也會拋出相同的例外。所以,我的問題是
- 這是因為 fileStream 物件而發生的嗎?它在 using 陳述句中,所以它沒有被肯定地處理掉。第一次上傳嘗試后的流位置會出現問題嗎?
- 重試同一個 Task 物件是否正常?我應該改變我做事的方式更好嗎?
uj5u.com熱心網友回復:
這是因為
fileStream物件而發生的嗎?它在 using 陳述句中,所以它沒有被肯定地處理掉。第一次上傳嘗試后的流位置會出現問題嗎?
是的,這是您的問題之一。每當讀取流時,它Position不會自動重置為 0。如果您嘗試重新讀取它,那么它將不會讀取任何內容,因為該位置位于流的末尾。
因此,您要么每次都必須創建一個新流,要么將流倒回到開頭。
重試同一個 Task 物件是否正常?我應該改變我做事的方式更好嗎?
每當任務完成時(無論是特定結果還是例外),重新執行await或檢索它Result都不會觸發重新執行。它將簡單地回傳值或例外。
因此,您必須為每次重試嘗試創建一個新任務。為此,您可以預期Func<Task<T>>您的RunWithRetries
public static T RunWithRetries<T>(Func<Task<T>> issueRequest)
{
...
issueRequest().GetAwaiter().GetResult();
}
從呼叫方來看,它看起來像這樣:
RunWithRetries(() => externalAPI.UploadAsync(fileRequest, new FileStream(...)));
//or
RunWithRetries(() => { fileStream.Position = 0; externalAPI.UploadAsync(fileRequest, fileStream); });
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/366607.html
標籤:C# 。网 异步 节流 http-status-code-429
