我正在构建一个Xamarin iOS& Android应用程序,我想对所有失败的webcall实现重试功能,或者在断开连接的情况下,我已经在BLL端使用Polly,我想让用户有可能手动重试,如所示以上图片。
protected List<Task> _taskList;
_taskList.Add(Task.Run(async () =>
{
try
{
**// Webservice Call**
Task<UtilisateurDTO> utilisateurTask = UserFactory.Login(username, pwd,
App.Hardware.GetDeviceId());
UtilisateurDTO utilisateur = await utilisateurTask;
if (utilisateur != null)
{
InvokeOnMainThread(() =>
{
**// Set result to ui component**
});
}
}
catch (Exception ex)
{
InvokeOnMainThread(() =>
{
// Add action button "Retry" to snackBar
_snackBar = new TTGSnackbar("ex.Message", TTGSnackbarDuration.Forever, "Retry", (obj) => {
// **Retry all tasks**
Parallel.ForEach(_taskList, task => task.Start());
});
_snackBar.Show();
});
}
}));
我知道无法重试已完成的任务,我无法在任务之外调用我的Web服务(不阻止UI线程),那么替代方案是什么?
使用解决方案进行更新
如果你想在一个地方处理异常并重试,这是我的解决方案(不是最好的重新加载所有内容的原因)
// BaseViewClass
public abstract class BaseViewController:UIViewController
{
// Function to override in child controllers
protected abstract void ReloadData(TTGSnackbar obj);
public void HandleExceptions(Exception e)
{
// On commence par cacher la ProgressBar
InvokeOnMainThread(HideLoadigProgressBar);
if (e is ConnectionLostException)
{
Console.WriteLine("ConnectionLostException: " + e.ToString());
InvokeOnMainThread(() =>
{
_snackBar = new TTGSnackbar("Connection lost !", TTGSnackbarDuration.Forever, "retry", ReloadData);
_snackBar.Show();
});
}
else if (e is TimeoutException)
{
Console.WriteLine("TimeoutException: "+ e.ToString());
InvokeOnMainThread(() =>
{
_snackBar = new TTGSnackbar("TimeoutException", TTGSnackbarDuration.Forever, "Retry", ReloadData);
_snackBar.Show();
});
}
.....................
}
// 其他ViewController
public partial class HomeController : BaseViewController
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
LoadData();
}
public void LoadData(){
Task.Run(async () =>
{
try
{
// Web calls
Task<UtilisateurDTO> getUserTask = AccueilFactory.GetUser();
UtilisateurDTO utilisateur = await getUserTask;
// Set UI result
}
catch(Exception ex) {
HandleExceptions(ex);
}
}
}
protected override void ReloadData(TTGSnackbar obj)
{
LoadData();
}
}
答案 0 :(得分:0)
您必须在异常时再次调用您的函数,而不仅仅是重新运行上一个任务。
您的代码将是这样的:
private void Login()
{
try
{
LoginInner(); // here you call service and update UI
}
catch (Exception ex)
{
InvokeOnMainThread(() =>
{
// Add action button "Retry" to snackBar
_snackBar = new TTGSnackbar("ex.Message", TTGSnackbarDuration.Forever, "Retry", (obj) => {
// **Retry all tasks**
Parallel.ForEach(_taskList, LoginInner); // ** call again loginInner **
});
_snackBar.Show();
});
}
}