Reputation: 697
We have a WPF control embedded in a WinForms control which is in turn exposed as an ActiveX control. This ActiveX is finally used in a C++ application developped by a third party.
At some point, the ActiveX control's UI becomes frozen, whereas the rest of the C++ application runs fine. After some debugging, I noticed that the WPF control was blocked on every call of Application.Current.Dispatcher.Invoke. However, the WinForms control processes its calls of Control.Invoke just fine. Whenever I pause the debugger, I can see that the UI thread is doing some work in the C++ application, but doesn't seem to be blocked or waiting for anything. It's as if the UI thread was suddenly and inexplicably refusing to execute the WPF delegates.
The WPF control sometimes enters this state when the C++ application monopolizes the UI thread for an extended period of time (a few minutes). The first thing I would do would be to use a different thread for such a time-consuming task, but as I already said, I'm not responsible for what the C++ application is doing. Anyway, this is no reason for my WPF control to behave in such a way. I have no idea how to solve this problem though; any help would be appreciated.
Upvotes: 4
Views: 2208
Reputation: 111
I would suggest running the MS Debug Diagnostics Tool - http://support.microsoft.com/kb/2580960.
We have had great results using this to identify COM interop blocking issues, which were in our case down to a pending COM finalizer blocking garbage collection. You can run it in various modes, but when run with the .NET analysis it will highlight any issues with the finalizer queue etc. It's a little clunky to run, but the info it gives you is gold.
Upvotes: 1
Reputation: 35881
The problem with Invoke
is that it's acts like a multi-threaded invocation; but it's really not, Invoke
is blocking--you're still only letting one thread at a time. Invoke
really just makes sure an action is executed on the UI thread. This is done by forcing a message into a message pump and executing it that way. That action might be blocked on something that the thread calling Invoke
needs to do to let the action continue.
For example:
lock(someLock)
{
dispatcher.Invoke(SomeMethod);
}
//...
public void SomeMethod()
{
lock(someLock)
{
//... do some work here
}
}
In this example, Invoke
is blocked invoking SomeMethod
while holding a lock. But, SomeMethod
wants the same lock
so it's blocked waiting for the lock
. You have a deadlock.
I would suggest using BeginInvoke
instead.
I don't know for sure if that's your problem because you haven't provided any code; but that's a very common problem with Invoke
. There's usually no reason to need Invoke
; if you think there is a need, that's usually an indication of a problem.
Upvotes: 0