开发者

Would it make sense to have two GUI threads for two independent forms?

At work we've got a very CPU-intensive Windows Forms application. It's running on a server with 24 cores.

As the Windows Forms model involves a single GUI thread processing a message pump, it seems that a rich, complex GUI is not making good use of the capabilities of the system. Am I wrong in saying this?

So my coworkers were discussing this. Our application just happens to involve two more-or-less independent forms. The idea came up to have the auxiliary form operate on its own dedicated thread, freeing up the app's main GUI thread to only process messages sent to the main form.

Presumably this would look something rather like this:

void CreateAuxiliaryForm()
{
    Action displayForm = () =>
    {
        var f = new AuxiliaryForm();
        f.ShowDialog();
    };

    displayForm.BeginInvoke(displayForm.EndInvoke, null);
}

Now, first of all, I don't know if this is safe to do at all. But my thinking is that since the two forms will be independent, it really ought to be OK for each one to have its own thread. Is this true?

I did say "more-or-less," and that's because I can't really say the two forms have no interaction whatsoever. But what my coworkers and I figured was that in any scenario in which the main form has to开发者_Python百科 interact with the auxiliary form in some way (say by one handling an event raised by the other), we would simply need to be sure to use Invoke/BeginInvoke to send any GUI-related code to the appropriate message pump.

What are people's thoughts on this idea?


Generally: Don't.

There are few possible reasons where threading the UI might help:

  • You are blocking the foreground thread for significant times (say > 5s) after a user action
  • You are blocking for notable time spans (>~300..500ms) not triggered by the user (e.g. through a periodic timer)
  • You have really expensive updates (rendering full-screen charts) and expect a dozen of these forms active.

Otherwise, there is no point, even for a "UI from hell" with hundreds of buttons and controls.

The only performance requirement for the UI is that it's smooth, meaning the user perceives UI responses to his actions as "instant" - which, for most actions is is 100..300ms (depending on the frequency of the action and the "size" of the response).

The downsides are many. WinForms is built on top of Win32 GUI, where threading "kinda works for top-level forms", but takes some care to get right. Internet Explorer uses spearate processes even, and some addins still manage to bring down all tabs when one page hangs.


I recently worked on a multi-form WinForms app that was very heavy on UI updates, i.e. it was spending most of its time in the forms' message-loops, specifically on timers and on painting operations. The individual forms themselves hardly interacted with one another at all, so cross-form UI dispatches wasn't an issue. In this case, I found that running dedicated UI threads for each form made a big difference to their responsiveness.

Btw, I prefer this pattern to launch a form on it's own message-loop, although your method should work as well:

new Thread(() => Application.Run(new Form1())).Start();


This should be OK as long as GUI updates happens on respective threads (using Control.Invoke) and any access to shared state is made via thread-safe way.

BTW, CPU intensiveness may indicate some processing/calculation - you can perhaps introduce parallelism there. Of course, that may mean a lot of changes.


I don't think you can buy yourself much running separate forms on separate threads. Take, for example, my CRT monitor. It refreshes at a maximum rate of 70 frames per second. This is regardless of how many threads I devote to updating the UI; it just plain can't push more frames per second. Your average movie theater updates the screen at only 24 frames per second, and still delivers the illusion of continuous animation.

You can avoid having one form interfering with updates on another form simply by delegating time-intensive processing to background threads. Creating additional threads for the UI will likely result in the extra threads idling most of their lifetime away, especially if you are not dealing in graphics-intensive applications.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜