4

所以我有一個方法必須執行三個任務。 第一項任務必須在另外兩項之前完成,可以並行執行。 這就是我現在所擁有的(修改爲簡單起見)寫入異步單點代碼

void facebookButtonClicked (object sender, EventArgs e) 
     { 
      View.Add (loadingOverlay); 
      AppDelegate.MobileService = new MobileServiceClient ("myserverUrl", "myApiKey"); 
      var users= AppDelegate.MobileService.GetTable<User>(); 
      var identities= AppDelegate.MobileService 
       .GetTable ("Identities"); 
      AppDelegate.MobileService 
       .LoginAsync (this, MobileServiceAuthenticationProvider.Facebook) 
        .ContinueWith (t => { 
       if (t.Status == TaskStatus.RanToCompletion) { 
          AppDelegate.mobileServiceUser = t.Result; 
          var task1 = users.InsertAsync(new User{BirthDate = DateTime.Now}); 
          var task2 = identities.ReadAsync(""); 
          Task.Factory.ContinueWhenAll(new Task[]{task1,task2},_=>{ 
           if(task1.Status==TaskStatus.RanToCompletion && task2.Status== TaskStatus.RanToCompletion) 
           { 
            var token = task2.Result 
             .GetArray()[0] 
             .GetObject() 
             .GetNamedObject ("identities") 
             .GetNamedObject ("facebook") 
             .GetNamedString ("accessToken");  

           SaveAuthorization (token); 
           NavigationController.PushViewController (new TabBarController(), false); 
           } 
          });    
         }}); 
     } 

的問題是(比林在異步代碼對於新手除外),當它試圖執行「PushViewController」我得到:

UIKit.UIKitThreadAccessException: UIKit Consistency error: you are calling a UIKit method that can only be invoked from the UI thread

我該如何重構/修改此代碼來修復它? 請幫忙。

回答

15

我打電話InvokeOnMainThread在我的異步方法可以使用匿名函數。

InvokeOnMainThread(() => { 
    NavigationController.PushViewController (new TabBarController(), false); 
}); 

如果由於某種原因,你是一個靜態類(像我),你可以做到這一點

new NSObject().InvokeOnMainThread(() => { 
    NavigationController.PushViewController (new TabBarController(), false); 
}); 
+0

如果有任何其他困惑的新Xamarin開發人員遇到這種情況,這個答案基本上與上面的答案相同,只使用lambda表達式而不是委託方法,同時還包括靜態類案例處理。 – woody121