2013-11-22 81 views
0

我有一个简单的登录屏幕,用于验证用户并使用Restful Web服务获取他们的数据。 Web服务正常工作,我打电话给他们获取数据,解析并存储在本地数据库中。问题是 - 我想在屏幕上添加一个活动指示器,而我这样做。我可以添加活动指示器,但是这个问题在控件去调用Web服务并获取数据时从不出现在视图上。在后台线程中调用Web服务并更新主线程上的UI

我如何在做背景时添加活动指标?

我也试图InvokeOnMainThread

 MonoTouch.UIKit.UIApplication.SharedApplication.InvokeOnMainThread(delegate{ 

      StartActivityIndicator(); 
      authenticateBtn.Enabled = false; 
      authenticateBtn.BackgroundColor = UIColor.Gray; 

     }); 
     // VALIDATE 
     bool isValid = ValidateTextbox(); 

     if (isValid == true) { 
      CreateUserAccount(); 
     } 

CreateUserAccount()方法调用Web服务和分析数据。如果我注释行CreateUserAccount()代码工作正常,我可以看到活动指标。 但是,因为我添加了CreateUserAccount()方法活动指标从不出现。

如何调用Web服务并执行UI活动。

回答

0

您可以通过在任务中分隔Web服务调用来解决此问题。这将在一个单独的线程上执行服务调用,当它完成时,您可以调用InvokeOnMainThread()来使用UI执行活动。

像这样的东西会工作,放在你的UIViewController。现在

Task CallWebService() 
{ 
    return Task.Factory.StartNew(() => { 
     // make your service call. 
    }); 
} 

,你可以在你的viewDidLoad中像这样调用这个:

// Inside ViewDidLoad method of your UIViewController 
// 
// Show your activity indicator first. 
StartActivityIndicator(); 
CallWebService().ContinueWith(task => { 

    if(task.isFaulted) 
     throw new AggregateException(task.Exception.InnerException.Message); 

    // Runs when the task is finished 
    InvokeOnMainThread(() => { 
     // Hide your activity indicator here. 
     StopActivityIndicator(); 
    }); 

}); 
+0

我有一种情况,只要我进入应用程序,我必须调用Web服务才能将未保存的数据发送回服务器,同时继续访问应用程序。我不知道在哪里调用InvokeOnMainThread,因为用户可能在任何视图上。我们如何处理这个问题。 – User382

1

直播与你的时间,使用C#5async/await

public async void DoSomething() 
{ 
    StartActivityIndicator(); 
    authenticateBtn.Enabled = false; 
    authenticateBtn.BackgroundColor = UIColor.Gray; 
    bool isValid = ValidateTextbox(); 

    if (isValid) 
     await CreateUserAccount(); 

    StopActivityIndicator(); 
} 
+0

也是有效的,但并不是每个人都使用异步与Xamarin的东西呢。 – therealjohn

+1

@therealjohn没有正当理由不要:) –

0

您可以将您的电话到CreateUserAccount在后台工作人员

var worker = new BackgroundWorker(); 
worker.DoWork += (s, ev) => ConnectToPanel(); 
worker.RunWorkerAsync();