iOSとAndroid用のXamarin.Formsアプリケーションを作成しています。Azureサーバーでデータとローカルsqliteデータベースとオンラインを保持しています。私のアプリは常にConnectivityプラグインでチェックしているインターネット接続が必要ですが、ユーザーが途中でセル受信を失った場合に例外がスローされることがあります。C#Polly async-await:再試行前にユーザーの確認を待つ
エラーが発生した場合、リクエストを再試行するためのすべてのサーバー要求を呼び出すことができるメソッドが必要です。私はまた、再試行する前にユーザーに入力を求める機能が欲しいと思います。流れは次のようになります。サーバーへ
コール - >例外がキャッチ - >彼らは再試行したい場合はユーザーに依頼 - >
を再試行私はのtry/catchを処理するように設定されているPollyパッケージを見つけましたが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
は表示されません。 2つのいずれかが起こる:
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
、誰もが知っています:
- を実行
System.AggregateException
次のメッセージがスローさを完了せずに何度も私のタスクを呼び出すために続けてタスクが失敗したときに実行を一時停止し、ユーザーが再開するのを待つ方法UPDATE:
Device.BeginInvokeOnMainThread
方法の内DisplayAlert
に電話を入れた後、私は今AggregateException
を回避する方法を発見しました。しかし、今私は別の問題があります。インターネットから接続を解除すると、
:DisplayAlert
が想定どおりにポップアップします。プログラムがonRetry
関数を終了する前に、再試行をクリックするのを待ちますので、RetryForeverAsync
待機が正しく機能しています。問題は、インターネットに再接続して再試行すると、もう一度やり直しが失敗するということです。だから私はインターネットに接続しているにもかかわらず、私は再接続を求められて無限ループに陥っています。RetryForeverAsync
は古い例外を単に再投げているようです。Task<TodoItem> t = App.MobileService.GetTable<TodoItem>().LookupAsync(id); WebExceptionCatcher<Task<TodoItem>, TodoItem> catcher = new WebExceptionCatcher<Task<TodoItem>, TodoItem>();
が、私はその後、接続が再確立されたときに再試行に失敗すると同じ結果とrunTask、両方を呼び出すの2種類の方法を試してみた:ここ
は私が
runTask()
を呼んでいる方法ですTodoItem item = await catcher.runTask(() => t);
か:
ありがとう、あなたは 'RetryForeverAsync'を試しましたか? – JSteward
ええ、それはAggregateExceptionを取得したときに実際に私が呼び出していたものでした。 – cvanbeek