编写异步的Monotouch代码

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一致性错误:您正在调用一个只能从UI线程调用的UIKit方法

我该如何重构/修改这段代码以修复它? 请帮忙。

2个回答

16

我在我的异步方法中调用InvokeOnMainThread并使用匿名函数。

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

如果因为某些原因你身处于静态类中(就像我一样),你可以这样做

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

如果其他困惑的新Xamarin开发人员遇到此问题,请注意,该答案基本与上面的答案相同,只是使用了Lambda表达式而不是委托方法,并包括静态类案例处理。 - woody121

8

我没有检查过这个,我面前也没有编译器。如果有错误请告知我。 - holmes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接