Agreed regarding the construction/Show() thing. You have to do it *all*
on the same thread.

As an aside, a quick experiment reveals that all appears to be fine if
you start the message pump on the worker yourself (with
Application.Run()), but it is still slightly rude, as that pool thread
will then have a message queue created for it that may not have existed
before. The hang only occurs if you create/show a window on the worker
thread and allow it to terminate without cleaning up at all.

As you don't get the same behaviour with your own Thread, this must be
something to do with the pool thread management that occurs as your
worker finishes.

Anyway, just to reiterate and rephrase your rule of thumb: Don't do
anything but fire-and-forget work on a system thread (e.g. ThreadPool,
Timer etc.)

M

-----Original Message-----
From: dotnet discussion [mailto:[EMAIL PROTECTED]] On Behalf Of
Ian Griffiths
Sent: 29 May 2002 15:49
To: [EMAIL PROTECTED]
Subject: Re: [DOTNET] Modeless WinForms Bug

I had assumed that he had created the window on one thread and then
called
Show on a different one.

In that case it wouldn't work, it's definitely wrong, but you also don't
get
an exception.

This is an instance of a more general problem: although it's positively
forbidden to use a Control from the wrong thread, you never actually get
any
indication from the runtime when you've done it wrong.  There is no
WrongThreadException.  This is disappointing, as it means that people
learning Windows Forms make this mistake time and again because there
are no
obvious symptoms that something is wrong.  It would be great if controls
actually checked the calling thread ID.  But we have been told in the
past
on this list that this was considered to be too expensive, and unfair on
the
code that actually gets it right...

However, if I misunderstood what was being said in *this* discussion,
and
*everything* was being done on the worker thread, then that's a slightly
different problem.  In that case, this is not the classic failure to
call
Control.Invoke, this is a slightly different error.  As you say, it
sounds
like an 'message pumps on a thread pool thread are not a good idea'
thing.

So I think we need to refer back to the original poster.  Jeff, what
exactly
are you doing?  Are you creating a form object on the timer thread?  Or
was
the form created elsewhere, and you are just trying to call Show from
the
timer thread?

(In any case the solution will be the same: don't do UI stuff on a
worker
thread - you don't own the worker thread.  Which means either don't use
the
System.Timers.Timer class, or if you must, use Control.Invoke to get the
real work done on the right thread.)


--
Ian Griffiths
DevelopMentor

----- Original Message -----
From: "Matthew Adams" <[EMAIL PROTECTED]>


> How would the Form know that it needed to throw an exception? As I
said,
> there is nothing intrinsically wrong with creating the Form and
calling
> Show() from the Timer thread. The 'no-return' behaviour you get is, I
> guess, because a message pump is started when you create the first
> window on a thread, and so it never comes back, not because it is a
> thread pool thread.
>
> So, essentially, it is all behaving correctly. Why would there be an
> exception?
>
> Matthew
>
> -----Original Message-----
> From: Jeff Roberts
>
> It sure would have saved me a lot of time if an exception had been
> thrown !

You can read messages from the DOTNET archive, unsubscribe from DOTNET,
or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

You can read messages from the DOTNET archive, unsubscribe from DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to