2

I am running a C# winform application that shows huge number of statistics and charts frequently. This application consist of multiple forms, each form has different output. When I open the task manager and check out the cpu usage, I find that only one core out of my eight cores is over loaded and the rest are doing nothing! Is there a way, for example, to assign each number of forms to a core. I need to improve the perfomance.

What I am looking for is to multithread my winforms such that each form would have a different thread that is running on a different core. Is that possible ?

The bottleneck is happening from loading the data into the controls.

Emo
  • 546
  • 4
  • 7
  • 22
  • Is the work literally all in the UI, or are you e.g. loading from databases or numbercrunching? – Rawling Oct 23 '12 at 13:16
  • Possible duplicate of [How do I spawn threads on different CPU cores?](http://stackoverflow.com/questions/32343/how-do-i-spawn-threads-on-different-cpu-cores) – Omar Oct 23 '12 at 13:17
  • 1
    That depends on where the CPU power goes. If it's all spent rendering on the UI thread, I think you're out of luck. Otherwise you'll have to benchmark and find bottlenecks, and address each of them. – CodeCaster Oct 23 '12 at 13:17
  • You'd need to split up the work behind the scenes into multiple threads. Ideally you don't want to do any number crunching in the UI, as a locked up UI is an unresponsive UI. If you Google 'Parallel .NET' there's plenty of new goodies in .NET 4.0 onwards that will help you with this. – Adrian Thompson Phillips Oct 23 '12 at 13:17
  • I am reading data from a socket and posting them on my winform. – Emo Oct 23 '12 at 13:18
  • No much to split, each thread is assigned for a winform, how can I slplit the winform thread ? – Emo Oct 23 '12 at 13:19
  • Is the bottleneck happening from reading/processing the socket data or from actually loading the data into the controls? – Dave New Oct 23 '12 at 13:33
  • don't load data into the UI too often – Oskar Duveborn Oct 23 '12 at 14:08

3 Answers3

2

It is possible to have multiple UI threads in a single WinForms application. Each UI thread must call Application.Run() and you'd need to mark the entry point to each with [STAThread] just like you do in the Main function.

I have successfully done this and it's a reasonable approach when faced with an existing codebase that's doing too much work on its UI thread. But... I would say this is a symptom of a design that could be improved in other ways. If you're doing too much work on your UI thread think about ways to get that work done on other threads. In my apps I've tried to get all non-trivial work done on non-UI threads. It can be done, but it's not always the fastest way to deliver software.

If doing no other work, a single UI thread is ample to draw 8 screens full of numbers and charts, and update them more frequently than a human can keep up. I know this to be the case :-)

Martin
  • 5,392
  • 30
  • 39
0

This is technically doable, more flexible in WPF than in WinForms (in my experience), but not recommended in either. Windows client apps tend to run with a single thread responsible for drawing the UI; typically background threads are used for background processing of data access or business logic. Additionally, you'd have to be doing a lot of work in the UI for rendering performance to actually be an issue - this sounds like unnecessary work to me.

However, the basic style in WinForms would be something like this:

var t = new Thread(() =>
        {
            var f = new Form1();
            Application.Run(f);
        })
t.Start();

Things you need to be aware of:

  • you will always have to Invoke calls between forms to make sure they're on the right thread.
  • if anything in your business layer has thread affinity, you'll need one instance per form that uses it.
  • application shutdown typically happens in response to the main thread's forms closing. You may need to handle your shutdown manually, though with the code above you have two message loops running and either will keep the app alive when the other's form closes.
Dan Puzey
  • 33,626
  • 4
  • 73
  • 96
0

Always do data crunching, receiving from I/O, parsing and whatnot on a separate thread or several threads if you need/want.

Then if you're loading a lot of data to UI controls, make sure you don't synchronize with the UI thread too often, like if you invoke every single item from an input stream separately and there are thousands of these per second - WinForms will grind to a halt.

Queue visual data changes in your background thread(s) and batch them to the UI thread with a minimum interval so as to not do this too often - the thread sync is expensive. AddRange is your friend.

Oskar Duveborn
  • 2,189
  • 16
  • 20