在WP7中从WS Async填充列表的最佳方法

时间:2011-11-10 10:32:37

标签: windows-phone-7 asynchronous listbox webserver

我有一个带有8个PanoramaItem的Panorama控件,每个PanoramaItem包含一个LongListSelector。使用MVVM,列表框绑定到ObservableCollection属性。

我需要从网络服务器中为每个列表填充数据(大量数据照片,文本..)。

如何在不阻止UI线程的情况下以最佳方式执行此操作?

我试过这样的事情

System.Threading.ThreadPool.QueueUserWorkItem(x => LoadList1());
System.Threading.ThreadPool.QueueUserWorkItem(x => LoadList2());
...

Load函数如下所示:

[EDIT] using Rx  
private IDisposable _disp;
private void LoadList1()
{
      _disp = Observable.FromEvent<PhotoEventArgs>(_webServer, "GetPhotosCompleted")
                        .Select(a => from l in a.EventArgs.Result
                                     where l.Name.Length > 1
                                     group l by l.Name.ToLower()[0] into c
                                             orderby c.Key
                                             select new Group<Photo>(c.Key, c))
                        .ObserveOnDispatcher()
                        .Subscribe(a =>
                        {
                             List1Items = new ObservableCollection<Group<Photo>>(a);
                             _disp.Dispose();
                        });

     _webServer.GetPhotosAsync();
}

它正在运行,但UI仍然在一段时间内被冻结。

如何让这个表现更好?

我想问题是我使用LongListSelector,所以我需要一次将所有数据添加到List1Items,以便LongListSelector分组正确。

编辑:Windows Phone工具包中存在一个错误 - 2011年11月(7.1 SDK) 将LongListSelector分组错误!

2 个答案:

答案 0 :(得分:1)

阻止UI线程的部分是将List1Items设置为整个结果集的地方,尝试在多次插入中分解,例如每次5或10。我是通过手机写的,所以很难给你一个代码示例,但看起来你的编码部分已经得到控制,只需要朝着正确的方向进行里尔踢。

答案 1 :(得分:0)

您应该考虑查看Reactive Extensions for Windows Phone

您的代码最终会看起来像这样:

private void LoadList1()
{
    Observable.FromEvent<PhotoEventArgs>(
        e => new EventHandler(e),
        e => _webServer.GetPhotosCompleted += e,
        e => _webServer.GetPhotosCompleted -= e
    ).Select(e => 
    {
        return 
            from l in e.Result
            where l.Name.Length > 1
            group l by l.Name.ToLower()[0]
            into c
            orderby c.Key
            select new Group<Photo>(c.Key, c);
    })
    .SubscribeOnDispatcher()
    .Subscribe(result => 
    {
        foreach (var item in result)
            List1Items.Add(item);
    });
}