So I have a method that must execute three tasks. The first task must be completed before the other two, which can be executed in parallel. This is what I have right now (modified for simplicity)
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);
}
});
}});
}
The problem is (other than Im a newb at async code) that when it tries to execute "PushViewController" I get:
UIKit.UIKitThreadAccessException: UIKit Consistency error: you are calling a UIKit method that can only be invoked from the UI thread
How can I refactor/modify this code to fix it? please help.
I call InvokeOnMainThread and use an anonymous function in my asynchronous methods.
InvokeOnMainThread(() => {
NavigationController.PushViewController (new TabBarController(), false);
});
If for some reason you are in a static class (like I was), you can do this
new NSObject().InvokeOnMainThread(() => {
NavigationController.PushViewController (new TabBarController(), false);
});
Take a look at InvokeOnMainThread or BeginInvokeOnMainThread
http://docs.xamarin.com/ios/Guides/Advanced_Topics/Threading#Developing_Responsive_Applications
NavigationController.BeginInvokeOnMainThread (delegate {
NavigationController.PushViewController (new TabBarController (), false);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With