mlemay
mlemay

Reputation: 1637

Best way to use Thread in a complex/single window WPF application

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

MSDN

Working With The WPF Dispatcher

Upvotes: 3

Views: 883

Answers (3)

Jeroen
Jeroen

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

MBen
MBen

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

Kent Boogaart
Kent Boogaart

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

Related Questions