tags:

views:

1155

answers:

4

We have a MFC 8 application compiled with /CLR that contains a larger amount of Windows Forms UserControls wich again contain WPF user controls using ElementHost. Due to the architecture of our software we can not use HwndHost directly. We observed an extremely strange behavior here that we can not make any sense of:

When the CPU load is very high during startup of the application and there are a lot live of ElementHost instances, the whole property engine completely stops working. For example animations that usually just work fine now never update the values of the bound properties, they just stay at some random value after startup. When I set a property that is not bound to anything the value is correctly stored in the dependency property (calling the getter returns the new value) but the visual representation never reflects that. I set the background to red but the background color does not change.

We tested this on a lot of different machines all running Windows XP SP2 and it is pretty reproducible.

The funny thing here is, that there is in fact one situation where the bound properties actually pickup a new value from the animation and the visual gets updated based on the property values. It is when I resize the ElementHost or when I hide and reshow the parent native control. As soon as I do this, properties that are bound to an animation pickup a new value and the visuals rerender based on the new property values - but just once - if I want to see another update I have to resize the ElementHost.

Do you have any explanation of what could be happening here or how I could approach this problem to find it out? What can I do to debug this? Is there a way I can get more information about what WPF actually does or where WPF might have crashed? To me it currently seems like a bug in WPF itself since it only happens at high CPU load at startup.

+2  A: 

I don't do any work with those techs, so I can't really speak to that. However, to me it sounds like some kind of deadlock is occurring in your code which is blocking calls to redraw() (or its equivalent). Resizing the window will force a redraw, but your normal mechanism for telling it to redraw when you've changed something might be blocked.

Is it possible you have a race condition in your code somewhere? On a lightly-loaded system things might happen in the correct order, but on the heavily loaded one the timing might be different. Perhaps that's triggering a deadlock in your code?

If you can attach a debugger, take a look at the threads that are running. If you can see what each thread is waiting on and what else it holds locks on (You can do this with Java, not sure about your app) that might help you determine where it's dying.

Herms
The funny thing is that the windows forms control is propertly redrawn. I can see the wpf controls properly even if the controls invalidate and are redrawn but the contained WPF elements do not update when I change properties of them.
bitbonk
In WPF there is no redraw (or equivalent) it is a Direct3D window.
bitbonk
+1  A: 

Most of the time, select isn't broken (as the saying goes).

It does sound very much like some kind of race or deadlock as @Herms suggests.

You could of course check MSDN for known bugs. Depending on what your code is like, when I'm really stuck with a bug I find that removing chunks of code until you're left with a minimal test case usually helps.

Greg
A: 

Nothing strange happens in your application. Dependency system "stops working" because of the fact, that UI thread, all the system relies to is busy. It's all about priorities for different Disparcher objects. I can consider you to use background processes doe for prolong operations, while all synchronization done in UI thread. Also, you can play with task prioritization (DispatcherPriority enum as first parameter of Invoke/BeginInvoke methods) Another tip, can help you is to implement DoEvent pattern, known from WinForms (to process messages in windows queue) To summarize, you should remember, that you're working in STA. Also, when you're using ElementHost in Windows XP, you actually remove hardware acceleration. Try to use .NET 3.5 SP1 to fix it somehow, but still you have to leave CPU for rendering and dispatching things.

Tamir
But the actual problem here is that after the startup (wich has high CPU usage) the CPU usage goes down to 1-2% but the WPF controls still do not update - and the dispatcher doesn't seem to to its job anymore animation values do no increase and AS A RESULT the view is not updated).
bitbonk
I already use .NET SP1 uncluding the new hotfixes from two days ago.
bitbonk
.NET 3.5 SP1 + Hotfixes
bitbonk
Are you sure, you have nothing halted during "high CPU startup". Please try to enable exception handing (in VS Debug->Exception-> check Vs there) and see if everything is ok
Tamir
+1  A: 

Their is no detail on how you load your data on startup... If you do not do it yet, consider using Dispatcher.BeginInvoke (with a priority lower than render) or a BackgroundWorker

Here is a post on how to do this!

PS. Just be careful if your objects that you bind to is a ObservableCollection<>... Read more about the issues I had doing this here

rudigrobler
Actually there is no data to be loaded at startup, it's just the complex controls.
bitbonk
They change their appearance by directly setting some properties on the windows forms user control (wich will be applied to similar properties of the contained WPF user control) at a much later time long after the app has loaded. Some animations start at startup though.
bitbonk
What I don't understand is: After startup of the application the CPU usage goes down to 1-2%. But the dispatcher still doesn't do its job Animations do not update the bound dependency properties and AS A RESULT the view is not updated. Properties change oncewhen I hide/show the winform user control.
bitbonk