2010-08-17 68 views
0

我在使用后台工作人员创建我的对象模型时遇到了麻烦。如何从backgroundWorker线程创建通用控件?

据我了解为什么,我无法找到解决方法。

这里是伪逻辑:

  • 呼叫web服务异步

  • 接收。当,在Load方法背景

  • 打开背景工人,和数据装载到控制,搜索现有对象,如果找不到,则创建一个新对象。

所有创建的对象都从Control继承(具有透明抽象层)。

虽然我在主线程创建控件,功能,做工精细:

public static T Find<T>(ObservableCollection<T> collection, int objectId) 
     where T : FormaliteBaseControl, new() 
    { 
     foreach (T item in collection) 
     { 
      if (item.ObjectId == objectId) 
       return item; 
     } 

     return new T(); 
    } 

当然,从后台线程调用时,一个跨线程异常的“新T()” 发生在Silverlight ,无法同步调用Dispatcher.Invoke。

虽然我以这种方式创建了大约450个对象,但我希望将对象模型创建保留在后台而不会降低Thread.Sleep或其他“好”方法的性能。

感谢您的回答。

+0

将450个UI控件放入什么类型的容器?一个ItemsControl或列表框?什么是虚拟化? – WiredPrairie 2010-08-17 12:22:16

+0

由于您使用的是线程,因此您可能会遇到与您正在使用的集合有关的问题 - 如果您是从另一个线程修改集合(而另一个线程正在使用枚举器,则通过foreach)。 – WiredPrairie 2010-08-17 12:23:39

回答

0

您是否正在创建实际的UI控件?这就是我所暗示的。如果是这样的话,将它委托给后台线程似乎没有意义。为什么?因为最终都是UI对象,所以它们必须在UI线程上创建。我知道你担心封锁,但是你的所有主要工作都必须被整理回UI。

可能最好的情况是提供一个pub/sub模型。您可以将具有逻辑的线程产生到后台线程,但永远不会实例化一个对象。相反,它会发布请求。在UI线程上,您可以侦听并创建对象。无效扩展(Rx)对此特别有用,因为您可以将ObservableCollection转换为Observable,然后将迭代集中到UI。

0

谢谢你们俩。

我的控件构建了一个树形图。 实际上,根对象包含4个扩展器,其中有一个itemcontrol作为子项(包含45个对象)。这些子对象中的每一个都有一个带有itemscontrol的扩展器,有大约10个孩子。

@WPCoder:作为ItemsControl的很少包含10点以上的对象,很少45,因为项目可以有多个高度和儿童,虚拟化did'nt帮我(是的,我已经试过)

经过一些测试后,我发现这是花时间的模板步骤。我的对象声明适合在第二个。所以我使用了一种解决方法来保持第一个深层对象在对象模型变大时折叠。 用户保持在启动时强制扩展的可能性作为参数,但他们知道这种方法的后面。

@Jeremy,我想MVVM是实现您的解决方案的最佳解决方案? 我会阅读Reactive Extensions。谢谢。