我可以在WPF中更改Control的Thread Affinity(Dispatcher)吗?

时间:2010-09-10 12:52:53

标签: wpf multithreading dispatcher

我想创建一个控件,需要一段时间才能创建(Pivot),然后将其添加到可视树中。为此,我需要在将控件添加到VisualTree之前更改控件的调度程序(及其heirachy)。

这可能吗?步行控制树和通过反射设置_dispatcher字段有什么影响吗?

2 个答案:

答案 0 :(得分:0)

AFAIK这只适用于Freezable派生类。我看到的最佳解决方案是在UI线程上创建控件并在创建过程中显示进度条。为了实现这一点,您必须在部分中创建控件,让进度条偶尔更新一次。这不仅对进度条是必需的,而且还将确保您的应用程序不会阻止。

伪代码(额外线程中的execure):

this.Dispatcher.BeginInvoke(UpdateProgress(0));
this.Dispatcher.BeginInvoke(bigControlBuilder.Build(0,25));
this.Dispatcher.BeginInvoke(UpdateProgress(25));
this.Dispatcher.BeginInvoke(bigControlBuilder.Build(25,50));
this.Dispatcher.BeginInvoke(UpdateProgress(50));
this.Dispatcher.BeginInvoke(bigControlBuilder.Build(50,75));
this.Dispatcher.BeginInvoke(UpdateProgress(75));
this.Dispatcher.BeginInvoke(bigControlBuilder.Build(75,100));
this.Dispatcher.BeginInvoke(UpdateProgress(100));
this.Dispatcher.BeginInvoke(this.Children.Add(bigControlBuilder.GetControl()));

更新:

为了使复杂的控制更具响应性,您还可以尝试UI-Virtualization / Data-Virtualisation:

仅加载并显示当前对用户可见的数据项的可视项目。不要加载和显示在屏幕外滚动的可视项目要小到可以看到或以任何其他方式对用户不可见。在userinteraction卸载变为invisble的项目时,加载可见的项目。

答案 1 :(得分:0)

要回答你的问题,我认为可能使用反射设置_dispatcher,但我根本不推荐它。在线程亲和性和STA的WPF中有一个根深蒂固的概念,所以我不会搞砸它。

比特克的方法很好。 我们在我们项目中使用的另一种方法是创建第二个UI线程,并在第一个UI线程构建UI时由第二个UI线程呈现进度指示器。只要进度条保留在第二个UI线程拥有的可视树中,您就应该很好。