Xamarin重试失败的数据请求
Retry action ImageXamarin重试失败的数据请求
我建立一个Xamarin的iOS & Android应用程序,我想实现一个重试功能,所有失败webcall或断开的情况下,我已经在BLL端使用波莉,我想给用户手动重试的可能性,如上面的图片所示。
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();
}
}
你必须在异常时再次调用你的函数,而不是只重新运行上一个任务。
您的代码将是这样的:
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(); }); } }
谢谢,我会尝试使用适当的代码更新主题 – nabenzine
你为什么要在一个异常再次运行所有任务,为什么不只是再次运行故障的任务吗? – Ygalbel
这不是问题,即使我只想运行一个故障任务,task.Start()也会发出异常,因为您无法再运行已完成的任务 – nabenzine
是的。但是如果您知道哪些任务失败,您可以重新创建它。在你的情况下用'UserFactory.Login(用户名,密码, App.Hardware.GetDeviceId())' – Ygalbel