In the following example, could HasStarted() ever return false (meaning
that ThreadJob() would get called *after* Foo() returns)?

Basically I don't ever want Foo() to return until after the thread has
executed.

------

void Foo() {
Thread thread = new Thread(ThreadJob);
thread.Start();

if (HasStarted(thread)) {
thread.Join();
}
}

void HasStarted(Thread t) {
return
t.ThreadState & (ThreadState.Stopped | ThreadState.Unstarted)) == 0;
}

------

I ask because I don't know for sure what exactly happens when
Thread.Start() is called.

Re: Thread.Start() by Jon

Jon
Sun Sep 04 13:23:17 CDT 2005

Cool Guy <coolguy@abc.xyz> wrote:
> In the following example, could HasStarted() ever return false (meaning
> that ThreadJob() would get called *after* Foo() returns)?
>
> Basically I don't ever want Foo() to return until after the thread has
> executed.

Two questions occur to me:

1) Why not just use thread.Join() without checking the thread state?
2) Why use a separate thread in the first place?

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Re: Thread.Start() by Cool

Cool
Sun Sep 04 13:38:30 CDT 2005

"Jon Skeet [C# MVP]" <skeet@pobox.com> wrote:

>> In the following example, could HasStarted() ever return false (meaning
>> that ThreadJob() would get called *after* Foo() returns)?
>>
>> Basically I don't ever want Foo() to return until after the thread has
>> executed.
>
> Two questions occur to me:
>
> 1) Why not just use thread.Join() without checking the thread state?

Because if you Join() on a thread in certain thread states, you wait
indefinitely.

> 2) Why use a separate thread in the first place?

The example in the OP is simplified.

In the application I have in mind (basically a telnet client), I fear there
may be a race condition involved in attempting to stop a thread too soon
after attempting to start it (by the user first choosing to establish a
connection and then choosing to disconnect straight after, for example).

Re: Thread.Start() by Cool

Cool
Sun Sep 04 13:58:46 CDT 2005

Cool Guy <coolguy@abc.xyz> wrote:

>> 1) Why not just use thread.Join() without checking the thread state?
>
> Because if you Join() on a thread in certain thread states, you wait
> indefinitely.

Hmm -- then again, I guess that the thread's ThreadState could change just
after I test it and before I call Join() anyway.

So right now I'm thinking of just using Join() with a timeout value of 500
miliseconds or so.

Re: Thread.Start() by Jon

Jon
Sun Sep 04 14:12:07 CDT 2005

Cool Guy <coolguy@abc.xyz> wrote:
> > Two questions occur to me:
> >
> > 1) Why not just use thread.Join() without checking the thread state?
>
> Because if you Join() on a thread in certain thread states, you wait
> indefinitely.

Well, only if the thread it joins doesn't terminate, surely. What
exactly are you worried about?

> > 2) Why use a separate thread in the first place?
>
> The example in the OP is simplified.
>
> In the application I have in mind (basically a telnet client), I fear there
> may be a race condition involved in attempting to stop a thread too soon
> after attempting to start it (by the user first choosing to establish a
> connection and then choosing to disconnect straight after, for example).

Trying to *stop* a thread could potentially cause problems - but then I
always prefer to stop threads in a more co-operative manner anyway. I
can't see why joining a thread which you've called Start on should
cause problems.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Re: Thread.Start() by Cool

Cool
Sun Sep 04 15:12:33 CDT 2005

"Jon Skeet [C# MVP]" <skeet@pobox.com> wrote:

>>> 1) Why not just use thread.Join() without checking the thread state?
>>
>> Because if you Join() on a thread in certain thread states, you wait
>> indefinitely.
>
> Well, only if the thread it joins doesn't terminate, surely.

Hmm. I could've sworn I found cases where Thread.Join wouldn't return even
though the thread *did* terminate; however I am unable to reproduce this
right now.

So I'm thinking now that perhaps in my previous testing there was a bug
(perhaps a deadlock) causing my thread to not terminate, and that that's
why Thread.Join() wouldn't return. I'll have to look into this.

>>> 2) Why use a separate thread in the first place?
>>
>> The example in the OP is simplified.
>>
>> In the application I have in mind (basically a telnet client), I fear there
>> may be a race condition involved in attempting to stop a thread too soon
>> after attempting to start it (by the user first choosing to establish a
>> connection and then choosing to disconnect straight after, for example).
>
> Trying to *stop* a thread could potentially cause problems - but then I
> always prefer to stop threads in a more co-operative manner anyway. I
> can't see why joining a thread which you've called Start on should
> cause problems.

One potential problem I can think of right now is a thread's ThreadState
not being immediately set to something other than ThreadState.Unstarted
after Start() has been called on it [*]. However, I'd guess that this
wouldn't happen, but I'm not sure.

[*] since (from the documentation):

| You cannot invoke Join on a thread that is in the ThreadState.Unstarted state.

Re: Thread.Start() by Jon

Jon
Sun Sep 04 16:05:59 CDT 2005

Cool Guy <coolguy@abc.xyz> wrote:
> > Trying to *stop* a thread could potentially cause problems - but then I
> > always prefer to stop threads in a more co-operative manner anyway. I
> > can't see why joining a thread which you've called Start on should
> > cause problems.
>
> One potential problem I can think of right now is a thread's ThreadState
> not being immediately set to something other than ThreadState.Unstarted
> after Start() has been called on it [*]. However, I'd guess that this
> wouldn't happen, but I'm not sure.
>
> [*] since (from the documentation):
>
> | You cannot invoke Join on a thread that is in the ThreadState.Unstarted state.

According to the docs for Thread.Start, however, that sets the state to
ThreadState.Running, from which it won't go back to Unstarted. While
it's possible that both are slightly wrong, I suspect it's unlikely
that just Start is wrong in that way.

While the thread may not have entered the method indicated by the
ThreadStart delegate, I think it would be pretty awful if you couldn't
reliably call Join on a thread you'd started.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Re: Thread.Start() by Cool

Cool
Sun Sep 04 16:39:22 CDT 2005

"Jon Skeet [C# MVP]" <skeet@pobox.com> wrote:

>> One potential problem I can think of right now is a thread's ThreadState
>> not being immediately set to something other than ThreadState.Unstarted
>> after Start() has been called on it [*]. However, I'd guess that this
>> wouldn't happen, but I'm not sure.
>>
>> [*] since (from the documentation):
>>
>>| You cannot invoke Join on a thread that is in the ThreadState.Unstarted state.
>
> According to the docs for Thread.Start, however, that sets the state to
> ThreadState.Running, from which it won't go back to Unstarted. While
> it's possible that both are slightly wrong, I suspect it's unlikely
> that just Start is wrong in that way.

The only thing that made me unsure was the wording:

| Causes the operating system to change the state of the current instance to ThreadState.Running.

But I guess it should be safe, as, like you said, it would be pretty bad if
you couldn't reliably Join on a thread started within the current thread.

Thanks for your support. You got me thinking more clearly as usual.

BTW -- it seems from our similar hostnames and IPs that we're now both on
the same ISP. I recently switched from Wanadoo/Freeserve myself. :)