在C# .NET Standard中,为何用位测试(ThreadState & (Stopped | Unstarted)) == 0判断线程Running状态?
为什么在C# .NET Standard中用
(ThreadState & (Stopped | Unstarted)) == 0判断线程是否运行? 这事儿得从ThreadState枚举的设计说起——它是带[Flags]特性的枚举,意味着一个线程可以同时处于多个状态(比如同时是Running + Background)。这也是为什么我们不能直接用简单的相等判断来检测状态的核心原因。
关键问题:Running状态的值是0
ThreadState.Running的枚举值被定义为0,这就导致了一个尴尬的情况:你没法直接用thread.ThreadState == ThreadState.Running来判断线程是否在运行。比如,如果线程同时处于Running和Background状态,它的ThreadState值是Running | Background(也就是0 | 0x00000004 = 0x00000004),这时候和Running(0)做相等判断会返回false,但线程实际上是在运行的。
反向判断的思路:排除“非运行”状态
既然没法直接检测0值的Running,那我们就反过来——排除那些明确表示“线程没在运行”的状态:
ThreadState.Unstarted:线程还没开始执行ThreadState.Stopped:线程已经停止执行
当我们用位运算(thread.ThreadState & (ThreadState.Stopped | ThreadState.Unstarted)) == 0时,逻辑是这样的:
- 如果线程处于
Unstarted或Stopped(实际不会同时出现这俩状态),位与的结果会等于对应的状态值(非0),说明线程没在运行 - 如果线程处于任何运行相关的状态(比如
Running、Running | Background、WaitSleepJoin等),位与的结果会是0,说明线程没有处于“未启动/已停止”的状态,也就是当前处于运行(或暂停但未终止)的状态
补充说明
API文档里特意强调这一点,就是因为新手很容易踩坑——直接用== Running会漏掉那些带有额外状态位的运行中线程。而通过位掩码排除非运行状态,才能准确覆盖所有线程处于活跃(未终止、已启动)的场景。
内容的提问来源于stack exchange,提问作者user5389726598465
相关产品推荐
相关产品推荐

