简体   繁体   English

在Windows Phone 8上运行异步REST调用时更新UI

[英]Update UI while running async REST call on windows phone 8

In short, I want to display a progress indicator, make a REST service call, and hide the indicator. 简而言之,我想显示进度指示器,进行REST服务调用,并隐藏指示器。

My progress indicator is bound to a property which when set to true or false, show or hides it. 我的进度指示器绑定到一个属性,当设置为true或false时,显示或隐藏它。 My indicator is a little spinning wheel and I obviously don't want my UI to hang when I make a the web service call, so this is done by calling an Async function. 我的指示器是一个小轮子,当我进行Web服务调用时,我显然不希望我的UI挂起,所以这是通过调用异步功能来完成的。

I found some code earlier on which works great to achieve what I want to do, however there is a but! 我之前发现了一些代码,它可以很好地实现我想做的事情,但是有一个但是!

Here is the simplified version code I'm using: 这是我正在使用的简化版本代码:

try
{
    ThreadPool.QueueUserWorkItem(async data =>
        {
            var dispatcher = Deployment.Current.Dispatcher;
            dispatcher.BeginInvoke(() =>
            {
                this.IsRunning = true;
            });

            configModel = LoginUser(loginId, password);

            dispatcher.BeginInvoke(() =>
            {
                this.IsRunning = false;
            });
        });
}
catch (Exception ex)
{
    IDialogService dialogService = this.GetService<IDialogService>();
    dialogService.Show("Unhandled Exception", ex.Message);
    dialogService = null;
}

The problem occurs when my web service fails for whatever reason ie blocked by firewall for example. 当我的Web服务因任何原因(例如被防火墙阻止)失败时,会出现此问题。 Even though I have a try catch, it doesn't get caught and crashes my app. 即使我有一个尝试捕获,它不会被抓住并崩溃我的应用程序。

Is there another way to achieve this without using the threadpool? 有没有另一种方法来实现这一点而不使用线程池? What's the cleanest way to achieve this? 实现这一目标的最简洁方法是什么?

I really need to call the this.IsRunning as this looks after showing and hiding my progress indicator but this obviously needs to be running on the UI thread, while the rest call needs to be running on another thread. 我真的需要调用this.IsRunning,因为这会显示并隐藏我的进度指示器,但这显然需要在UI线程上运行,而其余的调用需要在另一个线程上运行。

You need to try/catch the actual service call, not the QueueUserWorkItem: 您需要尝试/捕获实际的服务调用,而不是QueueUserWorkItem:

try
{
    configModel = LoginUser(loginId, password);
}
catch (...)
{

}

dispatcher.BeginInvoke(() =>
{
    this.IsRunning = false;
});

Otherwise, your IsRunning = false will never execute. 否则,您的IsRunning = false将永远不会执行。

However 然而

If you want the cleanest way, then you make LoginUser asynchronous so you can await it. 如果你想要最干净的方式,那么你使LoginUser异步,这样你就可以等待它。

this.IsRunning = true;

try
{
    configModel = await LoginUser(loginId, password);
}
catch (...)
{
    // report error here
}

this.IsRunning = false;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM