Re: Advanced Windows Form message priority / threading.
From: Ian Griffiths [C# MVP] (ian-interact-sw_at_nospam.nospam)
Date: 11/30/04
- Next message: Jon Skeet [C# MVP]: "Re: try catch finally"
- Previous message: Willy Denoyette [MVP]: "Re: asp.net security"
- Next in thread: Brian Keating EI9FXB: "Re: Advanced Windows Form message priority / threading."
- Reply: Brian Keating EI9FXB: "Re: Advanced Windows Form message priority / threading."
- Messages sorted by: [ date ] [ thread ]
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.
- Next message: Jon Skeet [C# MVP]: "Re: try catch finally"
- Previous message: Willy Denoyette [MVP]: "Re: asp.net security"
- Next in thread: Brian Keating EI9FXB: "Re: Advanced Windows Form message priority / threading."
- Reply: Brian Keating EI9FXB: "Re: Advanced Windows Form message priority / threading."
- Messages sorted by: [ date ] [ thread ]