I have an application with 2 UI threads.
The Main UI thread has a Main window with a XamDockManager and a DocumentContentHost Control which contains a Pane.The second UI thread opens a Window with a ListBox, and starts a timer that inserts an item on ListBox every second.
When the main window pane's close button is clicked, a MessageBox is displayed in the RequestBeforeClose handler.
The problem appears when the second thread's window get focused while the main thread's MessageBox is displayed.
NOTE: If I show the MessageBox in other point of main thread there is not any problem, the problem seems appear when the MessageBox is shown from RequestBeforeClose handler.
The second thread gets suspended and every DispatcherOperationCallbacks (ListBox insertions) get queued until main thread's MessageBox is closed
I Attach a C# solution that reproduces this problem.
Any ideas how to fix this?
Thanks.
It seems like a problem in the WPF framework. Basically it will lock in the FindCommandBinding of the CommandManager while it is executing the command. As such when another thread gets into that method it too will lock on that method and essentially wait for the other thread to complete it's handling of that method which is where you are currently showing the message box. I've submitted the issue to MS. You should probably try to avoid any long running operations directly within those operations.
Hi Andrew, Thanks for your help. The attached program is a simulation of the identified problem, what I really want to do is ask for saving changes before closing the tab, so i would like display a modal dialog that locks the main thread, in order to cancel (or not) the tab closure.
could it be done in other way? if not, I will avoid that question in order to not locking the thread...
Thank you very much
Nothing simple comes to mind since you basically would have to ensure that no routed command is being executed (at least via the FindCommandBinding method in the CommandManager). So for this specific scenario that could mean re-templating the TabGroupPane and use your own command instead of the TabGroupPane.CloseSelectedItemCommand. Then put up your prompt and assuming it is not cancelled then execute the TabGroupPane.CloseSelectedItemCommand. But I'm sure you want to handle the other cases for which the item would have been closed so perhaps another option is to handle the event, set e.Cancel to true and then start a deferred action (e.g. begininvoke) and if the user doesn't cancel it then close the pane but keep some flag so you don't cancel it and start a deferred action.
MS replied on the connect issue I submitted that this issue was previously fixed in a hotfix so you may want to get that.
Hi Andrew,
How can i download this hotfix?
.Net 4.5, Win7: http://support.microsoft.com/kb/2848798/en-us
Based on what is stated in those support pages it would seem that you need to contact MS' support: "To resolve this problem immediately, contact Microsoft Customer Support Services to obtain the hotfix.".
It worked!
The .NET Framework hotfixes worked successfully.
Thank you very much Andrew.