Franklin Gray wrote:
> everything that I know of runs on the UI thread unless you
> program it to run on a seperate thread.  

However, he asked about the System.Timers.Timer, and by default that
raises events on a thread pool thread...  (Although as others have
pointed out, you can change that by setting the SynchronizingObject
property.)

In fact, it's rather misleading suggest that most things run on the UI
thread.  Most things don't even know what the UI thread is.  Generally
speaking, only things that are aware of Windows Forms, or of
ISynchronizeInvoke will deliver event notifications on the UI thread.
And most things don't.

With the exception of Windows Forms-aware controls, most things that
perform asynchronous callbacks, or which raise events asynchronously
will do so on a non-UI thread.  So by default, you should usually
presume that event callbacks come in on the wrong thread, unless you
have a good reason to suppose otherwise.


Just to be clear, it's things that call you back *asynchronously* you
need to worry about.  Anything that can deliver you an event of its own
accord when something interesting happens, you need to wonder what
thread it's going to use to do that.  Windows Forms controls always use
the UI thread to notify you, but most things don't.


.NET v2.0 will change this slightly.  It introduces application-level
infrastructure that enables classes to cooperate with whatever threading
model the application requires.  This is exposed through the new
AsyncOperationManager class.  This abstracts away application framework
threading issues, making it possible for a class to raise events on the
UI thread, regardless of whether Windows Forms, Avalon, or something
else is being used.  (Windows Forms and Avalon use significantly
different systems for getting calls onto the right thread.)

So in .NET v2.0, things like web service proxies generated by VS.NET
integrate with this.  That means that if you start and async web service
operation, it will notify you on the UI thread when the operation
completes.  But in .NET v1.1 (i.e. the current version...) you get these
notifications on thread pool threads.  After all - how would these event
sources even know what the UI thread is?  Prior .NET v2.0, there was no
standard documented way of discovering what the UI thread is!  So you
can't reasonably expect to get events delivered on the UI thread...

Even in .NET v2, you shouldn't just assume that everything will use the
UI thread. Only classes that choose to make use of this new
infrastructure will do so.  You should still assume that async
notifications of any kind (whether they are events, or some other kind
of callback) will not come in on the UI thread unless you have a good
reason to presume otherwise.

And it gets slightly worse...  Even if you are using a class that you
know makes use of this new infrastructure to raise events on the UI
thread, it can still go wrong!  It only works if you gave the element in
question the opportunity to discover what the UI thread is.  For
example, suppose you were to create a web service proxy object on a
worker thread, and kick off some async work on that worker thread.
(Slightly odd thing to do, but it's certainly possible.)  Despite the
fact that the proxy is aware of the new thread sync infrastructure, it
won't actually raise completion notifications on the UI thread in this
case!

Why?  Well you never called it on the UI thread, so it never got to find
out which was the UI thread...  And if you're thinking: can't it just
ask this new fangled infrastructure "which is the UI thread?" that
doesn't work - there might be lots of UI threads!  People commonly refer
to "the UI thread" but it's just a shorthand for "the relevant UI
thread".  You can create as many UI threads as you like.


Even if you're absolutely completely sure you'll be called back on the
right thread, you should add an Assert to check...


public partial class SomeForm : Form
{
  ...

  private void ThinksItsCalledOnUiThread()
  {
    Trace.Assert(!InvokeRequired);
    ...
  }
  ...
}

I wouldn't usually bother with that code for an event handler for a
control.  But I would for any other code that handles an async event,
and assumes it's running on the UI thread.


-- 
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/

-----Original Message-----
From: Franklin Gray

everything that I know of runs on the UI thread unless you program it to
run on a seperate thread.  Running processing on seperate threads frees
up
the UI thread to do other things.  Take for example loading a form with
a
grid on it.  That grid needs to retrieve data from the DB.  Sometimes
that
takes time.  If you kick off a seperate thread to poll the DB, then the
UI
can continue to load the form while the CPU is waiting on the response
from the server to return the data.  Doing multi-threading isn't easy so
don't try it for the first time unless you have time to get over the
learning curve or you have a definate requirement to do it.

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to