我正在为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