我有一个使用Silverlight和C#的Windows Phone 7应用程序。此应用程序有一个方法可以触发多个Web服务请求。在我的代码中的另一点,我有一些代码如下所示:
myProgressBar.Visibility = Visibility.Visible;
while (AreWebServiceCallsDone() == false)
{
// Need "waiting" code here
}
// Proceed
如何在不锁定用户界面的情况下让我的用户界面“等待”一小段时间,然后再次检查以查看我的网络服务是否已完成?
谢谢!
答案 0 :(得分:2)
答案是不要让UI等待,而是“按照(异步)流程”进行操作。
最终,C#5中的异步内容将解决这一特定问题,但桌面CLR的发布没有时间表,更不用说Silverlight或WP7了。
我个人建议查看Microsoft.Phone.Reactive
,它是Reactive Extensions(Rx)的WP7版本,并附带SDK。这是一个相当大的主题,需要花费大量时间来解决问题,但可以真正简化您处理异步方案的方式。
假设您的每个Web服务都返回不同类型的数据,我会:
Do
“查看”消息并执行副作用(例如在本地分配值)Select
“规范化”类型,使它们的类型相同(下一步所需)ForkJoin
并行执行每个请求,并在每个请求完成时进行处理 1 为您的请求创建IObservable实际上取决于您使用的异步模式。假设你正在使用WebClient
,这里是一个扩展方法,它从DownloadStringAsync
创建一个Observable作为样本(它可能看起来很复杂,但它只是处理错误和取消):
public static class ObservableWebClient
{
public static IObservable<string> DownloadStringObservable(
this WebClient webClient, Uri uri)
{
return Observable.Create(observer =>
{
var disposable = new CompositeDisposable();
var completedObservable = Observable.FromEvent<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs
>(
h => new DownloadStringCompletedEventHandler(h),
h => webClient.DownloadStringCompleted += h,
h => webClient.DownloadStringCompleted h= h
);
disposable.Add(completedObservable
.SelectMany(ev =>
{
return (ev.EventArgs.Error != null)
? Observable.Throw<string>(ev.EventArgs.Error)
: Observable.Return(ev.EventArgs.Result);
})
.Subscribe(observer));
disposable.Add(Disposable.Create(
() => webClient.CancelAsync()));
return disposable;
});
}
}
然后您可以这样使用它:
请注意,我已跳过Do
+“规范化”步骤,因为我的数据类型都是相同的(字符串)。因此,我可以将它们全部订阅为一个数组(如果你想知道的话,这是ForkJoin
如何工作的微妙之处)
var webClientA = new WebClient();
var webClientB = new WebClient();
var webClientC = new WebClient();
Observable.ForkJoin(
webClientA.DownloadStringObservable(uriA),
webClientB.DownloadStringObservable(uriB),
webClientC.DownloadStringObservable(uriC),
)
.ObserveOnDispatcher()
.Subscribe(dataArray =>
{
// All three have completed
this.DataA = dataArray[0];
this.DataB = dataArray[1];
this.DataC = dataArray[2];
});
答案 1 :(得分:1)
您应该使用异步回调方法并处理进度条对回叫事件的可见性。
使用 while ,您正在让UI等待线程执行。
我在我的博文中使用了这种方法:http://www.infopoint.com/News-Events/EntryId/29/Building-a-WP7-RSS-reader-Part-1-Basics.aspx