我正在爲iOS和Android創建一個Xamarin.Forms應用程序,用於保存數據和本地sqlite數據庫並在Azure服務器中聯機。雖然我的應用程序需要互聯網連接,而且它始終使用Connectivity插件進行檢查,但我發現如果用戶丟失了信元接收請求,我有時會發生異常。C#Polly async-await:在重試前等待用戶確認
我想要一個方法,我可以調用我所有的服務器請求,以便在發生錯誤時重試請求。我還希望能夠在重試之前詢問用戶輸入。流程是這樣的:
呼叫服務器 - >捕獲到異常 - >詢問用戶是否要重試 - >重試
我發現Polly包,它是建立處理的try/catch在C#中重試。目前,我有我的代碼的設置是這樣的:
public class WebExceptionCatcher<T, R> where T : Task<R>
{
public async Task<R> runTask(Func<T> myTask)
{
Policy p = Policy.Handle<WebException>()
.Or<MobileServiceInvalidOperationException>()
.Or<HttpRequestException>()
.RetryForeverAsync(onRetryAsync: async (e,i) => await RefreshAuthorization());
return await p.ExecuteAsync<R>(myTask);
}
}
我RefreshAuthorization()
方法簡單地顯示在主線程當前頁面上DisplayAlert
:
private async Task RefreshAuthorization()
{
bool loop = true;
Device.BeginInvokeOnMainThread(async() =>
{
await DisplayAlert("Connection Lost", "Please re-connect to the internet and try again", "Retry");
loop = false;
});
while (loop)
{
await Task.Delay(100);
}
}
當調試這一點,並把我的互聯網連接。從不顯示DisplayAlert
。兩種情況之一發生:
- 繼續執行一遍又一遍地打電話給我的任務沒有完成
- 一個
System.AggregateException
拋出以下消息:
System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. ---> System.Net.Http.HttpRequestException: An error occurred while sending the request
有誰知道如何在任務失敗時成功暫停執行,並等待用戶恢復?
UPDATE:
把呼叫DisplayAlert
的Device.BeginInvokeOnMainThread
方法的內部之後,我現在已經找到了AggregateException
周圍的一種方式。但是,現在我有另一個問題。
一旦我斷開與互聯網的連接,DisplayAlert
就會彈出它應有的樣子。程序等待我在完成onRetry
功能之前單擊重試,以使RetryForeverAsync
等待正常工作。問題是,如果我重新連接到互聯網,然後重試,它會再次失敗,並再次失敗。所以,即使我連接到互聯網,我仍被困在被要求重新連接的無限循環中。看來RetryForeverAsync
只是重新拋出舊的異常。
這是我如何我打電話runTask()
:
Task<TodoItem> t = App.MobileService.GetTable<TodoItem>().LookupAsync(id);
WebExceptionCatcher<Task<TodoItem>, TodoItem> catcher = new WebExceptionCatcher<Task<TodoItem>, TodoItem>();
我再打過電話runTask,都與失敗的重試重新建立連接時的結果相同的兩種不同的方式:
TodoItem item = await catcher.runTask(() => t);
或:
謝謝,你嘗試過'RetryForeverAsync'嗎? – JSteward
是的,這實際上是我在收到AggregateException時調用的那個 – cvanbeek