Reputation: 1637
I want to know what is the best solution to improve my WPF application.
I know that WPF forces you to do all the UI work on the thread that created the UI. This is a major problem for me, because my UI is very huge and I only have 1 window, so I cannot split 1 thread per window.
When I do pan and zoom, everything needs to be refresh every time, one of my CPU hit 100% usage until all is done.
So I'll try to explain what I have in my application:
So just my application where I can do pan and zoom (without the 10 displays), there is a lot of lag du to the amount of controls, and when I put the display, it double the lag...
My application takes about 1.5 gb of virtual memory.
I searched to use the dispatcher to makes threads when I can but I don't find what I want... everywhere they talked about 1 thread/window... but I only have 1 Window, don't know what to do.
So here is the real question: Where can I create new threads to help my render time? To split the job to different CPU...
I found different website where they talked about this... but not answering my question:
Running WPF Application with Multiple UI Threads
Working With The WPF Dispatcher
Upvotes: 3
Views: 883
Reputation: 449
I would 'fake' those controls and paint them ones into a background when zooming. You could even draw small images that looks like the controls. You can speed up the zooming, when using a smaller (scaled) background. Then when ready, i cannot imagen that 2k controls need to be used at the same time, so only repaint or add the controls that can be seen/operated. Calculating the x,y of every control and check if they are present in the viewrectangle and drawing them, is a lot faster than drawing them all.
Most of the spectactular graphics are done with these kind of tricks.
Upvotes: 0
Reputation: 3996
So I searched a bit on that. One Application can create a different Window or Page in a different thread : piece of code taken from here
private void OnCreateNewWindow(
object sender,
RoutedEventArgs e)
{
Thread thread = new Thread(() =>
{
Window1 w = new Window1();
w.Show();
w.Closed += (sender2, e2) =>
w.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
So that was the good news. But in your case that doesn't really apply, since you have one Window, and I tried this it doesn't really work :
private void OnCreateNewWindow(object sender, RoutedEventArgs e)
{
SynchronizationContext syncContext = SynchronizationContext.Current;
var btn = sender as Button;
var st = btn.Parent as StackPanel;
Thread thread = new Thread(() =>
{
Button button = new Button();
syncContext.Post(delegate { st.Children.Add(button) ;}, null); //Exception here
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
I tried to create a separate control in a different thread, which works, but then when I try to add it to the stackPanel it fails with the InvalidOperationException
I know it doesn't directly answer you question, but I least you know that all controls in the same Window
must belong to the same thread.
Upvotes: 2
Reputation: 178650
It sounds like you need to be using virtualization more than anything else. The user can only see a small part of the virtual workspace at any time, so you should only be refreshing that part.
Other than that, have you profiled? What is it exactly pegging your CPU?
Upvotes: 1