WPF in WinForms: blocked on Dispatcher.Invoke, although UI thread is alive

We have a WPF control built into the WinForms control, which, in turn, appears as an ActiveX control. This ActiveX is finally used in a C ++ application developed by a third party.

At some point, the ActiveX management user interface becomes frozen, while the rest of the C ++ application is working fine. After some debugging, I noticed that the WPF control was blocked every time I called Application.Current.Dispatcher.Invoke. However, WinForms management handles Control.Invoke calls just fine. Whenever I pause the debugger, I see that the UI thread does some work in the C ++ application, but does not seem to be blocked or waiting for anything. It is as if the user interface thread suddenly and inexplicably refused to execute WPF delegates.

A WPF control sometimes enters this state when a C ++ application monopolizes the UI thread for a long period of time (several minutes). The first thing I would like to do is use a different thread for such a time-consuming task, but, as I said, I am not responsible for what the C ++ application does. In any case, this is no reason for my WPF control to behave this way. I have no idea how to solve this problem; Any help would be appreciated.

+4
source share
2 answers

I would suggest running the Debug MS diagnostic tool - http://support.microsoft.com/kb/2580960 .

We got great results, using this to identify the COM blocking issues that we had in our case before the COM compiler blocking garbage collection was pending. You can run it in various modes, but when launched with .NET analysis, it highlights any problems with the finalizer queue, etc. This is a little inconvenient to run, but the information it gives you is gold.

+1
source

The problem with Invoke is that it acts like a multi-threaded call; but it really is not, Invoke blocks - you still only allow one thread at a time. Invoke really just ensures that the action is executed in the user interface thread. This is done by forcing a message into the message pump and executing it. This action may be blocked by what is required to invoke the Invoke thread in order to continue the action. For instance:

 lock(someLock) { dispatcher.Invoke(SomeMethod); } //... public void SomeMethod() { lock(someLock) { //... do some work here } } 

In this example, Invoke blocks when SomeMethod called, holding the lock. But, SomeMethod wants the same lock , so it blocks waiting for the lock . You have a dead end.

I would suggest using BeginInvoke .

I do not know for sure if this is your problem, because you have not provided any code; but this is a very common problem with Invoke . There is usually no reason to need Invoke ; if you think there is a need, this usually indicates a problem.

0
source

Source: https://habr.com/ru/post/1432024/


All Articles