Re: Advanced Windows Form message priority / threading.

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Ian Griffiths [C# MVP] (ian-interact-sw_at_nospam.nospam)
Date: 11/30/04


Date: Tue, 30 Nov 2004 12:40:18 -0000

This may not seem like the most helpful of suggestions, but I think it's
pragmatic:

  Don't do that!

Specifically, if you find yourself wanting to send messages to the UI thread
hundreds of times a second, that's probably a mistake. It's almost
certainly going to be better in such a situation to have a timer running on
the UI thread that periodically polls to see what has changed, and perform
updates if necessary.

This will solve the priority problem - the System.Windows.Forms.Timer class
uses Win32 windows timers, which send very low priority messages, so your
clicks will always take precedence.

It will also mean the system probably spends less time simply refreshing the
screen - it's always more efficient to do batched display updates than it is
to draw each and every update independently. In naive update
implementations you can find that you've actually spent most of your CPU
cycles repainting stuff, and very little time getting useful work done. The
user can only read updates so fast, so there's not much point trying to
update more than 10 times a second anyway. (Unless you're doing animation -
that's different. But for actual changes of information, even 10 updates a
second is probably more than is necessary.)

In short, sending hundreds (or even tens) of Invoke or BeginInvoke messages
to the UI thread every second is never going to be a useful thing to do.

As to what the *right* thing to do is... Well that depends on what you're
trying to achieve. Polling with a UI thread timer might be a good approach.
Or you might want to use some mechanism for throttling the rate at which you
deliver BeginInvoke calls - never queue up another one until the previous
one has been processed and never deliver them faster than some particular
rate, for example.

-- 
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/
DevelopMentor - http://www.develop.com/
"Brian Keating EI9FXB" wrote:
> Hello again,
> I've already placed a few posts on this topic.
> This time i've a simple application that exhibits my problem,
> I've placed sample solution 8k on my website should anyone be interested 
> in
> having a look. http://briankeating.net/transfer/test.zip
>
> To recap the problem I expected (and found).
> I've a main GUI thead (main form), this GUI thread has an UpdateTextBox
> function that appends a string in a textbox and It also has a button that
> stops my worker thread(s) form calling Invoke on main thead.
>
> private void UpdateTextBox(string strText)
> {
> System.Diagnostics.Debug.Assert(InvokeRequired != true, "Invoke was
>                                   required", "calling begin invoke not on
> the gui thread");
> richTextBox1.Focus();
> richTextBox1.AppendText(strText);
> }
>
> When my form loads I start two worker threads and these threads just loop
> around and call Invoke on my main Form with a string to display.
>
> private void ThreadEntryPoint()
> {
> while (!bStop)
> {
> string str = "Thread Id: " + GetHashCode() + ",\t" + nCount.ToString() + "
> This is a passing string\r\n";
>
> Invoke(new UpdateTextboxDelegate(UpdateTextBox), new object[] {str});
> Interlocked.Increment(ref nCount);
> //Thread.Sleep(1000); //slow sending
> Thread.Sleep(10); //fast sending
> } //end while
>
> MessageBox.Show(Thread.CurrentThread.ToString() + "  thread closing");
> }
>
> Now if my worker threads are slow sending i.e. I call Thread.Sleep(1000);
> i.e. wait a seond between each invoke call on the gui thread, then I have 
> no
> problem I can click my button and the event handler is called
>
> private void button1_Click(object sender, System.EventArgs e)
> {
>    bStop = true;
> }
>
> However if my two threads are sending fast (only waiting 10 miliseconds)
> then my GUI thread is so busy processing these update events that if i 
> click
> the stop button nothing happens.
>
> ... Hope that kinda clears things up about a GUI thread becoming 
> unresponsive.
>
> So what are my options?
> I'm thinking that Inovke is basically like SendMessage so maybe somehow i
> can replace the windows message loop to do the following, (basically
> prioritised message queue)
> loop
>   peek all windows messages and process them, (get/dispatch)
>   then peek for one of my Inoke calls (get/dispatch)
> endloop
>
> Now people that have helped me already may be asking what has as this to 
> do
> with windows running in different threads, well the reason I want to do 
> this
> is, say for example i have 2 windows in my application, one window is busy
> receiving messages from a worker thread (so this is gonna become
> unresponsive), i wouldn't like all other windows to become unresponsive 
> too),
> switching between windows will require my busy thread to handle some 
> window
> messages (loose focus maybe etc) so a prioritised message queue will allow
> this, hey maybe this is enough I'll keep at it and see what happens.
>
> But I gues this post comes down to one question,
> Is there anyway I can plug into a windows forms message queue and check 
> for
> pending invoke calls as described above?
>
> Thanks for any help
> Brian.
>
> p.s.
> This is only a sample test app, so it's not perfect for many a reason,
> I realise the two worker threads calling Invoke is pretty much the same as
> One worker thread calling invoke.
> clicking close on the forms gets executed straight away for some reason
> (maybe it's handled differently?)
> Clicking close will throw an exception cause i havn't stopped the worker
> thread(s) from sending. 


Relevant Pages

  • Re: Advanced Windows Form message priority / threading.
    ... > updates if necessary. ... > uses Win32 windows timers, which send very low priority messages, so your ... >> stops my worker threadform calling Invoke on main thead. ... >> I realise the two worker threads calling Invoke is pretty much the same as ...
    (microsoft.public.dotnet.languages.csharp)
  • Advanced Windows Form message priority / threading.
    ... I've a main GUI thead, this GUI thread has an UpdateTextBox ... stops my worker threadform calling Invoke on main thead. ... Now if my worker threads are slow sending i.e. ... can replace the windows message loop to do the following, ...
    (microsoft.public.dotnet.languages.csharp)
  • RE: Advanced Windows Form message priority / threading.
    ... If i want my Invoke calls in my message queue I prob have to use events? ... > I've a main GUI thead, this GUI thread has an UpdateTextBox ... > can replace the windows message loop to do the following, ... > I realise the two worker threads calling Invoke is pretty much the same as ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Downloading all updates after SP2
    ... > Is it possible to down load ALL the updates after SP2 in one hit. ... > there was an awful lot of updates to install (I stopped counting at ... > Where can i go to download all of the updates (i have a list from ... > Windows Update that i printed off before i abandoned the update on ...
    (microsoft.public.windowsupdate)
  • WARNING LONG - Brian Livingstons take on Windows Genuine Advantage
    ... Genuine Advantage is Microsoft spyware ... Some tech writers have said categorizing WGA as spyware is arguable. ... It causes serious problems for some legitimate Windows users and was sprung on customers with no notice other than a press release the day before. ... If an instance of Windows doesn't seem to have a valid license, display notices to the user and prevent any updates being downloaded from Microsoft.com except security upgrades that are rated "Critical." ...
    (alt.sys.pc-clone.dell)