1.创建一个线程
ThreadStart 委托,该委托没有参数,定义如下:
public delegate void ThreadStart();
下面代码创建和启动一个线程执行ExecuteInForeground方法.这些方法打印一些线程属性,该线程从开始到循环结束至少执行5S.
using System;
using System.Diagnostics;
using System.Threading;
public class Example
{
public static void Main()
{
var th = new Thread(ExecuteInForeground);
th.Start();
Thread.Sleep(1000);
Console.WriteLine("Main thread ({0}) exiting...",
Thread.CurrentThread.ManagedThreadId);
}
private static void ExecuteInForeground()
{
var sw = Stopwatch.StartNew();
Console.WriteLine("Thread {0}: {1}, Priority {2}",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.ThreadState,
Thread.CurrentThread.Priority);
do {
Console.WriteLine("Thread {0}: Elapsed {1:N2} seconds",
Thread.CurrentThread.ManagedThreadId,
sw.ElapsedMilliseconds / 1000.0);
Thread.Sleep(500);
} while (sw.ElapsedMilliseconds <= 5000);
sw.Stop();
}
}
输出结果:
从输出结果可以看出应用程序主线程退,但是ExecuteInForeground仍然在运行,为什么主线程结束了ExecuteInForeground仍然在运行呢? 在文章结尾我们会进行说明。
public delegate void ParameterizedThreadStart(object obj);
下面例子定义了一个有参委托,并将参数通过Thread的Start方法传进去。
using System;
using System.Diagnostics;
using System.Threading;
public class Example
{
public static void Main()
{
var th = new Thread(ExecuteInForeground);
th.Start(4500);
Thread.Sleep(1000);
Console.WriteLine("Main thread ({0}) exiting...",
Thread.CurrentThread.ManagedThreadId);
}
private static void ExecuteInForeground(Object obj)
{
int interval;
try {
interval = (int) obj;
Console.WriteLine("obj=" + interval);
}
catch (InvalidCastException) {
interval = 5000;
}
var sw = Stopwatch.StartNew();
Console.WriteLine("Thread {0}: {1}, Priority {2}",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.ThreadState,
Thread.CurrentThread.Priority);
do {
Console.WriteLine("Thread {0}: Elapsed {1:N2} seconds",
Thread.CurrentThread.ManagedThreadId,
sw.ElapsedMilliseconds / 1000.0);
Thread.Sleep(500);
} while (sw.ElapsedMilliseconds <= interval);
sw.Stop();
}
}
输出结果如下:
一旦启动线程,就没有必要保留对 Thread 对象的引用。线程继续执行,直到线程过程完成
2. 线程属性
属性 | 备注 |
ManagedThreadId | 当前线程ID |
Name | 当前线程名称 |
ThreadState | 当前线程的状态 |
IsBackground | 当前线程是否是一个后端线程 |
Priority | 当前线程优先级 |
IsThreadPoolThread | 当前线程是否是一个线程池线程 |
CurrentCulture | 当前线程语言文化 |
CurrentUICulture | 当前线程UI的语言文化 |
下面例子打印线程常用一些属性:
using System;
using System.Threading;
public class Example
{
static Object obj = new Object();
public static void Main()
{
ThreadPool.QueueUserWorkItem(ShowThreadInformation);
var th1 = new Thread(ShowThreadInformation);
th1.Start();
var th2 = new Thread(ShowThreadInformation);
th2.IsBackground = true;
th2.Start();
Thread.Sleep(500);
ShowThreadInformation(null);
}
private static void ShowThreadInformation(Object state)
{
lock (obj)
{
var th = Thread.CurrentThread;
Console.WriteLine("Managed thread #{0}: ", th.ManagedThreadId);
Console.WriteLine(" Thread Name:{0}",th.Name);
Console.WriteLine(" Thread ThreadState:{0}", th.ThreadState);
Console.WriteLine(" Background thread: {0}", th.IsBackground);
Console.WriteLine(" Thread pool thread: {0}", th.IsThreadPoolThread);
Console.WriteLine(" Priority: {0}", th.Priority);
Console.WriteLine(" Culture: {0}", th.CurrentCulture.Name);
Console.WriteLine(" UI culture: {0}", th.CurrentUICulture.Name);
Console.WriteLine();
}
}
}
输出结果如下:
3.前段线程(foreground thread)和后端线程(background thread)
默认情况下,通过下面两种方式创建的线程为前段线程:
-
应用程序主线程。
-
通过调用thread类构造函数创建的线程。
-
通过ThreadPool 线程池创建的线程.
-
从非托管代码进入托管执行环境的所有线程
using System;
using System.Diagnostics;
using System.Threading;
public class Example
{
public static void Main()
{
var th = new Thread(ExecuteInForeground);
th.IsBackground = true;
th.Start();
Thread.Sleep(1000);
Console.WriteLine("Main thread ({0}) exiting...",
Thread.CurrentThread.ManagedThreadId);
}
private static void ExecuteInForeground()
{
var sw = Stopwatch.StartNew();
Console.WriteLine("Thread {0}: {1}, Priority {2}",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.ThreadState,
Thread.CurrentThread.Priority);
do {
Console.WriteLine("Thread {0}: Elapsed {1:N2} seconds",
Thread.CurrentThread.ManagedThreadId,
sw.ElapsedMilliseconds / 1000.0);
Thread.Sleep(500);
} while (sw.ElapsedMilliseconds <= 5000);
sw.Stop();
}
}
输出结果如下,从输出结果我们可以看出应用程序主线程终止,ExecuteInForeground不会继续运行也会跟着退出
总结:
1.ParameterizedThreadStart ThreadStart委托可以创建一个线程。
2.线程相关联属性。
3.前段线程和后端线程的区别,如果想等待后端线程结束后再停止应用程序,需要使用特殊对象来实现线程通信。