0

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(); 
    } 
} 
+0

你为什么要在一个异常再次运行所有任务,为什么不只是再次运行故障的任务吗? – Ygalbel

+0

这不是问题,即使我只想运行一个故障任务,task.Start()也会发出异常,因为您无法再运行已完成的任务 – nabenzine

+0

是的。但是如果您知道哪些任务失败,您可以重新创建它。在你的情况下用'UserFactory.Login(用户名,密码, App.Hardware.GetDeviceId())' – Ygalbel

回答

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(); }); } }

+0

谢谢,我会尝试使用适当的代码更新主题 – nabenzine