【问题标题】:How might I create a generic control from a backgroundWorker thread?如何从 backgroundWorker 线程创建通用控件?
【发布时间】:2010-08-17 08:32:33
【问题描述】:

我在使用后台工作程序创建对象模型时遇到了麻烦。

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

这是伪逻辑:

  • 异步调用 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();
    }

当然,从后台线程调用时,“new T()”处会出现跨线程异常 在 Silverlight 中,无法同步调用 Dispatcher.Invoke。

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

感谢您的回答。

【问题讨论】:

  • 将 450 个 UI 控件放入什么类型的容器中? ItemsControl 还是 ListBox?虚拟化的东西?
  • 由于您使用的是线程,因此您可能会遇到正在使用的集合的问题 - 如果您正在从另一个线程修改集合(而另一个线程正在使用枚举器,通过foreach)。

标签: c# silverlight thread-safety backgroundworker new-operator


【解决方案1】:

您是否正在创建实际的 UI 控件?这就是我的意思。如果是这种情况,将其委托给后台线程似乎没有意义。为什么?因为最终都是 UI 对象,所以它们必须在 UI 线程上创建。我知道您担心阻塞,但您的所有主要工作最终都必须编组回 UI。

可能最好的情况是提供发布/订阅模型。您可以生成具有后台线程逻辑的线程,但它永远不会实例化对象。相反,它将发布请求。在 UI 线程上,您侦听并创建对象。 Reactive Extensions (Rx) 对此特别有用,因为您可以将 ObservableCollection 转换为 Observable,然后将迭代编组到 UI。

【讨论】:

    【解决方案2】:

    谢谢你们俩。

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

    @WPCoder:由于 itemscontrol 很少包含超过 10 个对象并且很少包含 45 个对象,并且因为项目可以有多个高度和子项,所以虚拟化对我没有帮助(是的,我已经尝试过)

    经过一些测试,我发现这次是模板步骤。我的对象声明马上就可以了。因此,当对象模型变大时,我使用了一种解决方法来保持第一个深层对象折叠。 用户保留在启动时强制扩展的可能性作为参数,但他们知道这种方法的倒退。

    @Jeremy,我认为 MVVM 是实现您的解决方案的最佳解决方案? 我会阅读响应式扩展。谢谢。

    【讨论】:

      猜你喜欢
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      • 1970-01-01
      • 2013-10-24
      • 2014-09-19
      相关资源
      最近更新 更多