C#笔记11 获取线程及其信息,什么是优先级、单元状态、线程状态、执行状态、线程名称以及其他属性?
前文讲完了在C#中线程怎么创建,怎么删除,怎么启动,怎么阻止。
现在来看看线程本身的属性。
当前线程
首先要获得当前线程,才能获取线程信息,此属性用于获取当前运行的线程。此属性可用于获取代码当前执行所在的线程。
public static System.Threading.Thread CurrentThread { get; }
展示线程信息的方法代码:
private static void ShowThreadInformation(String taskName)
{
String msg = null;
Thread thread = Thread.CurrentThread;
lock(lockObj) {
msg = String.Format("{0} thread information\n", taskName) +
String.Format(" Background: {0}\n", thread.IsBackground) +
String.Format(" Thread Pool: {0}\n", thread.IsThreadPoolThread) +
String.Format(" Thread ID: {0}\n", thread.ManagedThreadId);
}
Console.WriteLine(msg);
}
中间涉及很多没学的内容,暂且不提。
单元状态
一个过时的属性。
非过时的替代方法包括用于检索单元状态的 GetApartmentState 方法和用于设置单元状态的 SetApartmentState 方法。
In .NET Framework versions 1.0 and 1.1, the property marks a thread to indicate that it will execute in a single-threaded or multithreaded apartment. This property can be set when the thread is in the or thread state; however, it can be set only once for a thread. If the property has not been set, it returns :ApartmentStateUnstartedRunningUnknown
大意为:在 .NET Framework versions 1.0 and 1.1中,它标识着一个线程是启动一个单线程还是多线程的一部分。这个属性标记线程以指示它将在单线程或多线程单元中执行。当它处于or线程状态时可以被设置,(这里我没理解)它为一个线程只能设定一次。如果没有设定,他会返回:ApartmentStateUnstartedRunningUnknown 状态。
线程状态
在代码中这个状态经常用在判断条件中。
Thread.ThreadState
指示当前线程状态的 ThreadState 值之一。初始值为 Unstarted。
ThreadState 属性提供比 IsAlive 属性更具体的信息。具体可取值为枚举值:
中止 256 Aborted
线程状态包括 AbortRequested,线程现在已死,但其状态尚未更改为 Stopped。
中止请求 128 AbortRequested
已在线程上调用 Abort(Object) 方法,但线程尚未收到将尝试终止它的挂起 ThreadAbortException。
后台 4 Background
该线程作为后台线程执行,而不是作为前台线程执行。此状态通过设置 IsBackground 属性来控制。
运行 0 Running
线程已启动,但尚未停止。
停止 16 Stopped
线程已停止。
停止请求 1 StopRequested
正在请求线程停止。这仅供内部使用。
暂停 64 Suspended
线程已暂停。
暂停请求 2 SuspendRequested
正在请求线程暂停。
未启动 8 Unstarted
尚未在线程上调用 Start() 方法。
等待睡眠加入 32 WaitSleepJoin
线程被阻塞。这可能是调用 Sleep(Int32) 或 Join()、请求锁(例如,通过调用 Enter(Object) 或 Wait(Object, Int32, Boolean))或等待线程同步对象(如 ManualResetEvent)的结果。
IsAlive执行状态
不常用的一个属性。一个布尔值。
如果此线程已启动,但未正常终止或中止,此时为true;
否则。false
线程名称
public string? Name { get; set; }
string类型,包含线程名称的字符串或 null
(如果未设置名称)。
一般我们不怎么使用这个属性,你可以给线程添加名称以增强其在线程管理中的可读性,在添加之前可以与null比较,来知晓是否已经命名过,如果已经命名就调取当前名称。
线程优先级
public System.Threading.ThreadPriority Priority { get; set; }
代表线程在调度过程中的优先级,默认值为Normal。
在公共语言运行库内创建的线程将分配Normal,而在公共运行库外创建的线程在进入公共运行库中将保留之前的优先级。
CLR内部创建的线程:
- 当在CLR内部创建线程时(例如,使用
Thread
类),CLR会自动将线程的优先级设置为Normal
。- CLR还提供了一种机制来更改线程的优先级,但这种更改通常是在运行时进行的,而不是在创建线程时。
CLR外部创建的线程:
- 如果您在CLR外部创建线程(例如,使用
CreateThread
API),这些线程在进入CLR之前具有由操作系统定义的优先级。- 当这些线程开始执行CLR代码时,它们将保留之前的优先级。这意味着CLR外部创建的线程不会自动变为
Normal
优先级。
不同操作系统调度的算法不同,对于优先级的处理也不尽相同。
可能的取值:
AboveNormal 3 BelowNormal 1 Highest 4 Lowest 0 Normal 2 高于正常 3 Thread 可以调度在具有Highest优先级的线程之后,和具有Normal优先级的线程之前。 低于正常值 1 Thread 可以调度在具有Normal优先级的线程之后,和具有Lowest优先级的线程之前。 最高 4 可以将 Thread 调度在具有任何其他优先级的线程之前。 最低 0 可以将 Thread 调度在具有任何其他优先级的线程之后。 正常 2 Thread 可以调度在具有AboveNormal优先级的线程之后和具有BelowNormalNormal优先级的线程之前。默认情况下,线程具有此优先级。
开发时我们可以使用这个属性获取和设置该线程的优先级。
除此之外
其他属性
public System.Globalization.CultureInfo CurrentCulture { get; set; }
此属性返回的 CultureInfo 对象及其关联对象确定日期、时间、数字、货币值、文本的排序顺序、大小写约定和字符串比较的默认格式。请参阅 CultureInfo 类,了解区域性名称和标识符、固定区域性、非特定区域性和特定区域性之间的差异,以及区域性信息影响线程和应用程序域的方式。
public static System.Security.Principal.IPrincipal? CurrentPrincipal { get; set; }
获取或设置线程的当前负责人(对基于角色的安全性而言)
public System.Threading.ExecutionContext? ExecutionContext { get; }
获取一个 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息。
public bool IsBackground { get; set; }
获取或设置一个值,该值指示线程是否为后台线程。
public bool IsThreadPoolThread { get; }
获取一个值,该值指示线程是否属于托管线程池。
public int ManagedThreadId { get; }
一个整数,表示此托管线程的唯一标识符。
线程可以是后台线程,也可以是前台线程。后台线程与前台线程相同,不同之处在于后台线程不会阻止进程终止。属于某个进程的所有前台线程终止后,公共语言运行时将结束该进程。任何剩余的后台线程都将停止并且不会完成。
默认情况下,以下线程在前台执行(即,其 IsBackground 属性返回):false
- 主线程(或主应用程序线程)。
- 通过调用 Thread 类构造函数创建的所有线程。
默认情况下,以下线程在后台执行(即,其 IsBackground 属性返回):true
- 线程池线程,这是由运行时维护的工作线程池。您可以使用 ThreadPool 类配置线程池并计划线程池线程上的工作。
- 从非托管代码进入托管执行环境的所有线程。
注:基于任务的异步操作会在线程池线程上自动执行。
线程的标识符不会随着时间变化改变。