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