【问题标题】:Calling web services in background thread and update UI on main thread在后台线程中调用 Web 服务并在主线程上更新 UI
【发布时间】:2013-11-22 16:35:03
【问题描述】:

我有一个简单的登录屏幕,它使用 Restful Web 服务对用户进行身份验证并获取他们的数据。 Web 服务工作正常,我称它们为获取数据、解析并存储在本地数据库中。问题是 - 我想在执行所有这些操作时在屏幕上添加一个活动指示器。我可以添加活动指示器,但问题是,它永远不会出现在视图上,因为控件会调用 Web 服务并获取数据。

如何在后台执行操作时添加活动指示器??

我也尝试过 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 活动。

【问题讨论】:

    标签: c# web-services xamarin.ios threadpool


    【解决方案1】:

    珍惜时间,使用C#5async/await

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

    【讨论】:

    • 同样有效,但并不是每个人都使用 Async 和 Xamarin 的东西。
    • @therealjohn 没有正当理由不这样做:)
    【解决方案2】:

    您可以通过在任务中分离 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();
        });
    
    });
    

    【讨论】:

    • 我遇到这样一种情况,我一进入应用程序,就必须调用网络服务将未保存的数据发布回服务器,同时继续访问应用程序。我不知道在哪里调用 InvokeOnMainThread,因为用户可以在任何视图上。我们如何处理。
    【解决方案3】:

    您可以在后台工作人员中调用 CreateUserAccount

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

    【讨论】:

      猜你喜欢
      • 2012-06-17
      • 2015-03-20
      • 2012-07-21
      • 1970-01-01
      • 2018-07-16
      • 2017-11-29
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      相关资源
      最近更新 更多