I have large application which is not designed well. In particular on start it is initializing many services in the UI thread. The problem is that initialization could be time-consuming, so UI thread is freezing in the meantime. I can’t move it to background thread as some services relies on which thread they started and there’s simply too many code to check where it happens line-by-line.
The idea is to show loading screen with ProgressBar in separate thread with separate Dispatcher:
ThreadStart initLoadingDialog = () =>
{
_currentDispatcher = Dispatcher.CurrentDispatcher;
_dialogWindow = new MyDialogWindow();
_dialogWindow.Show();
Dispatcher.Run();
};
var thread = new Thread(initLoadingDialog);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
(Well, code is not exactly precise because I use MVVM and there’s no MyDialogWindowClass but rather just Window with Contents set to ViewModel and DataTemplate in resources. But it is not important ASAIK here).
It works, but seems uses some resources, thus effectively binding them to non-main-UI thread. And later I receive exception “Cannot convert the value in attribute ‘Background’ to object of type ‘System.Windows.Media.Brush’. The calling thread cannot access this object because a different thread owns it. Error at object ‘System.Windows.Controls.Border’ in markup file ‘PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml’.”
Well, what I want to is isolate this single dialog totally, so that it will have its own resources (in fact there’s just Grid with ProgressBar and two TextBlocks on it) and not use anything else. Is there a way to do this?
P.S. Or maybe someone knows how to determine which Brush resource exactly is in question? Because I only have this exception and nothing else… what is the source of the problem really?
UPD: It is ProgressBar. Its style uses some non-frozen brush and it binds to the thread.
I’m guessing that the brush that’s causing you a problem was instantiated at an earlier time on the main UI thread and that’s why your seeing your error. I think you might have to override the control templates of all the controls in your dialog and make sure that you freeze all the brushes.
Something like this:
Also, I believe that the dispatcher will continue to run after your window closes. You need to manually shut it down.. something like this: