2017-09-15 50 views
0

執行異步任務,我想執行下一次使用Xamarin:上啓動

  • 當應用程序啓動時啓動畫面立即呈現(我已經達到了這個以下一個教程https://channel9.msdn.com/Blogs/MVP-Windows-Dev/Using-Splash-Screen-with-Xamarin-Forms

  • 執行數據庫遷移如果有(用戶更新的應用程序,並在第一次運行)

  • 從數據庫中讀取用戶數據(用戶名和密碼),調用REST webservice來檢查用戶數據是否仍然有效。如果用戶的數據是有效的將用戶重定向到炫魅否則重定向到LoginPage

我讀過關於未來良好Xamarin.Forms Async Task On Startup後。當前代碼:

public class MainActivity :global::Xamarin.Forms.Platform.Android.FormsApplicationActivity 
{ 
    protected override void OnCreate (Bundle bundle) 
    { 
    base.OnCreate (bundle); 
    global::Xamarin.Forms.Forms.Init (this, bundle); 
    LoadApplication (new App()); // method is new in 1.3 
    } 
} 

// shared code - PCL lib for Android and iOS 
public partial class App : Application 
{ 
    public App() 
    { 
    InitializeComponent(); 
    // MainPage = new LoadingPage(); 
    } 
}  
protected override async void OnStart() 
{ 
    // Handle when your app starts 
    await App.Database.Migrations(); 
    if(await CheckUser()) // reads user data from db and makes http request 
    this.MainPage = new Layout.BrowsePage(); 
    else 
    this.MainPage = new LoginPage(); 
} 

如果MainPage在構造異常未設置被套上iOS和Android。我知道異步void不會等待,如果它不明確地有.Wait()- Async void,但這是否意味着執行線程仍然繼續它的工作。

執行線程命中時await App.Database.Migrations();它暫停執行並等待等待Task完成。同時它繼續它的工作(即LoadApplication()繼續執行,並期望現在設置App.MainPage)。我的假設是否正確?對於異步/等待我來說,我很新。

我只是想避免LoadingPage因爲三分屏顯示:

  • 閃屏(權當應用程序被啓動)
  • LoadingPage(DB遷移,HTTP請求,..)
  • BrowsePage或LoginPage

對於用戶體驗而言,理想的只是兩頁。

我弄成這個樣子,但我相信有一個更好的方法:

protected override void OnStart() 
{ 
    Page startPage = null; 
    Task.Run(async() => 
    { 
    await App.Database.Migrations(); 
    startPage = await CheckUser() ? new Layout.BrowsePage() : new LoginPage(); 
    }.Wait(); 
    this.MainPage = startPage(); 
} 
+0

你在'更好的方法'中尋找什麼?爲什麼你認爲顯示一個加載頁面是一個劣質的用戶體驗? –

+0

我想,如果應用程序需要5-8秒加載然後加載頁面就可以了。它向用戶顯示正在發生的事情(正在進行遷移......)。我測量了時間,啓動應用程序需要7秒(Samsung Galaxy A5)。 – broadband

回答

0

的另一種方法是添加每個要同時運行到任務列表,然後等待該項目的對全部。然後所有項目都將運行異步,但您仍然可以得到CheckUser的結果。我不知道它是否比你使用的更好,但它是另一種方式。否則,如果您正在等待每個功能,那麼它們不會同時運行。

protected async Task OnStart() 
    { 
     Page startPage = null; 
     //create a list of the items you want to run concurrently 
     List<Task> list = new List<Task>(); 
     list.Add(App.Database.Migrations()); 
     list.Add(CheckUser()); 
     //wait for all of them to complete 
     Task.WaitAll(list.ToArray()); 

     //get the result from the CheckUser call 
     Task<bool> checkUsertask = list[1] as Task<bool>; 
     if (checkUsertask.Result == true) 
      this.MainPage = new Layout.BrowsePage(); 
     else 
      this.MainPage = new LoginPage(); 
    } 

如果您不喜歡列表[1],那麼你可以將它添加到列表中,這樣你可以參考它一旦完成之前創建一個任務。

protected async Task OnStart() 
{ 
    Page startPage = null; 
    //create a list of the items you want to run concurrently 
    List<Task> list = new List<Task>(); 
    list.Add(App.Database.Migrations()); 
    var checkUserTask = CheckUser(); 
    //create this task directly so we can refer to it later to get the result 
    list.Add(checkUserTask); 
    //wait for all of them to complete 
    Task.WaitAll(list.ToArray()); 

    //get the result from the CheckUser call 
    if (checkUserTask.Result == true) 
     this.MainPage = new Layout.BrowsePage(); 
    else 
     this.MainPage = new LoginPage(); 
} 
+0

的OP正在更新數據庫,如果需要的話,並從中獲取_then_用戶信息。兩者不能同時運行,一個取決於另一個。 –

1

那麼你可以把一切都變成了應用程序的構造,以及濺射屏幕只會顯示一個較長的,同時加載的應用程序,但實際上我相信這是一個劣解。

有一個閃屏,然後加載頁面,看起來酷似濺射屏幕,但有一個進度條,或加載圖標,告訴它是做什麼的用戶,是一個更好的方法。

如果你必須在用戶看到第一頁之前這樣做,那麼加載屏幕是一個很好的選擇,讓用戶知道爲什麼它需要這麼長時間。

我想補充的唯一的另一件事,是存儲已經加載數據庫的布爾或版本號,這樣你就不會需要運行遷移代碼,除非你的應用程序的版本增加。

通過這樣做,你可以把這個布爾檢查你的應用程序的構造函數,並加載第一頁,立竿見影。如果需要遷移,然後加載頁面加載,並讓的OnStart完成遷移,然後加載第一個應用程序的屏幕。