In C# .NET standard why is the thread state "Running" determined using the bit test `(ThreadState & (Stopped | Unstarted)) == 0`

时间:2018-02-03 08:02:54

标签: c# multithreading

According to the documentation, :

Because the Running state has a value of 0, it is not possible to perform a bit test to discover this state. Instead, the following test (in pseudo-code) can be used:

if ((state & (Unstarted | Stopped)) == 0)   // implies Running

Threads are often in more than one state at any given time.

and api

The Thread.ThreadState property of a thread provides the current state of a thread. Applications must use a bitmask to determine whether a thread is running. Since the value for Running is zero (0), test whether a thread is running by using C# code such as (myThread.ThreadState & (ThreadState.Stopped | ThreadState.Unstarted)) == 0 or Visual Basic code such as (myThread.ThreadState And (ThreadState.Stopped Or ThreadState.Unstarted)) = 0.

Searching through SO (1,2,3) I only find why ThreadState should not be used for flow control since the state checked could immediately change. For cases when you check it for debugging why would you use the bitmask above as opposed to just myThread.ThreadState==0?

1 个答案:

答案 0 :(得分:1)

The enum / bit mask here is to restrict you to checking two bits. There are other bits in the status that do not tell you whether it is running or not - so them being set (1) or not set (0) doesn't change whether you should consider it running. For example, having the WaitSleepJoin bit set, or the SuspendRequested bit set - doesn't change that it is "running", for most useful purposes.

So: the state & (Unstarted | Stopped) says "just looking at these two bits, and ignoring the rest"...

The full set of documented flags are:

[Serializable, Flags, ComVisible(true)]
public enum ThreadState
{
    Aborted = 256,
    AbortRequested = 128,
    Background = 4,
    Running = 0,
    Stopped = 16,
    StopRequested = 1,
    Suspended = 64,
    SuspendRequested = 2,
    Unstarted = 8,
    WaitSleepJoin = 32
}

I say "documented", because enums aren't enforced - the value could theoretically come back as 2050 or -6 - with whatever bit flags are set for those.