有没有办法隔离WPF中使用的资源?

有没有办法隔离WPF中使用的资源?,wpf,multithreading,Wpf,Multithreading,我有一个设计不好的大型应用程序。特别是在启动时,它正在初始化UI线程中的许多服务。问题是初始化可能很耗时,所以UI线程在此期间会冻结。我不能将它移到后台线程,因为有些服务依赖于它们启动的线程,而且代码太多,无法逐行检查它发生在哪里 其想法是在单独的线程中使用ProgressBar和单独的Dispatcher显示加载屏幕: ThreadStart initLoadingDialog = () => {

我有一个设计不好的大型应用程序。特别是在启动时,它正在初始化UI线程中的许多服务。问题是初始化可能很耗时,所以UI线程在此期间会冻结。我不能将它移到后台线程,因为有些服务依赖于它们启动的线程,而且代码太多,无法逐行检查它发生在哪里

其想法是在单独的线程中使用ProgressBar和单独的Dispatcher显示加载屏幕:

ThreadStart initLoadingDialog = () =>
                                    {
                                        _currentDispatcher = Dispatcher.CurrentDispatcher;
                                        _dialogWindow = new MyDialogWindow();
                                        _dialogWindow.Show();
                                        Dispatcher.Run();
                                    };
var thread = new Thread(initLoadingDialog);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
(好吧,代码并不精确,因为我使用MVVM,没有MyDialogWindowClass,而只是在参考资料中将内容设置为ViewModel和
DataTemplate
的窗口。但在这里它并不重要)

它可以工作,但似乎使用了一些资源,从而有效地将它们绑定到非主UI线程。后来我收到了一个例外“无法将属性'Background'中的值转换为'System.Windows.Media.Brush'类型的对象。”。调用线程无法访问此对象,因为其他线程拥有它。标记文件“PresentationFramework.Aero,版本=3.0.0.0,区域性=中性,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=MSIL”中的对象“System.Windows.Controls.Border”处出错;组件/themes/aero.normalcolor.xaml'。”

我想完全隔离这个对话框,这样它就有了自己的资源(实际上只有一个网格,上面有ProgressBar和两个文本块),而不使用其他任何东西。有没有办法做到这一点

或者也许有人知道如何确定哪一个笔刷资源是有问题的?因为我只有这个例外,没有其他的…问题的真正根源是什么


UPD:它是
ProgressBar
。它的样式使用了一些非冻结的画笔,并绑定到线程。

我猜导致问题的画笔是早些时候在主UI线程上实例化的,这就是您看到错误的原因。我认为您可能必须重写所有单击对话框中的控件,并确保冻结所有笔刷

大概是这样的:

<LinearGradientBrush freezable:Freeze="True" 
xmlns:freezable="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
/>
_dialogWindow.Closed += (sender, e) => _dialogWindow.Dispatcher.InvokeShutdown();

我猜导致您出现问题的笔刷是在主UI线程上的较早时间实例化的,这就是您看到错误的原因。我认为您可能必须覆盖对话框中所有控件的控件模板,并确保冻结所有笔刷

大概是这样的:

<LinearGradientBrush freezable:Freeze="True" 
xmlns:freezable="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
/>
_dialogWindow.Closed += (sender, e) => _dialogWindow.Dispatcher.InvokeShutdown();

不,对话框正常显示并关闭。但当我显示一些对话框时,它失败了。只有一个对话框。不知道原因-这个具体的对话框与其他对话框有何不同……是的,我调用
InvokeShutdown()
事实上,问题中没有公开它。谢谢。无论如何,重新定义所有控件模板似乎是一项工作。即使只是ProgressBar。我知道Freezable,但问题是如何隔离(如果愿意,在需要时强制创建新控件)这个特定的对话框来自应用程序的其余部分,而不是如何安全地共享部分资源。Aero笔刷用于许多控件中,我认为在实例化后会存储在字典中。如果您的对话框使用的笔刷已经在字典中(在主UI线程中创建),反之亦然,你会有一个问题。为什么其他地方工作正常?我不敢相信aero的画笔只在一个对话框中使用。其他的一切(我检查了至少十几个对话框)有效。你指的是Microsoft.Win32对话框吗?如果是,我不认为这些对话框使用WPF样式系统。不,对话框正常显示并关闭。但是当我显示一些对话框时,它失败了。只有一个对话框。不知道原因-这个具体的对话框与其他对话框有何不同……是的,我调用
InvokeShutdown()
事实上,问题中没有公开它。谢谢。无论如何,重新定义所有控件模板似乎是一项工作。即使只是ProgressBar。我知道Freezable,但问题是如何隔离(如果愿意,在需要时强制创建新控件)这个特定的对话框来自应用程序的其余部分,而不是如何安全地共享部分资源。Aero笔刷用于许多控件中,我认为在实例化后会存储在字典中。如果您的对话框使用的笔刷已经在字典中(在主UI线程中创建),反之亦然,你会有问题。为什么其他地方工作正常?我不敢相信aero的画笔只在一个对话框中使用。其他所有东西(我检查了至少十几个对话框)都可以工作。你是指Microsoft.Win32对话框吗?如果是,我认为这些对话框不使用WPF样式系统。