使用System.Threading.Thread进行异步操作
操作系统实现线程并提供各种非托管API来创建和管理线程。CLR封装这些非托管西城,在托管代码中使用System.Threading.Thread类来公开它们。
const int printNum = 1000;
static void Main(string[] args)
{
ThreadStart threadStart = doWork;
Thread thread = new Thread(threadStart);
thread.Start();
for(int j = 0; j < printNum; j++)
{
Console.Write("-");
}
Console.ReadLine();
}
public static void doWork()
{
for (int i =0; i < printNum; i++) {
Console.Write("+");
}
}
输出
++++++++++++++++++++++±----------------+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++±---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++±-----------------------------------------------++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++±--------------------------------------------------------------------------------------------------------------------------------------++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++±---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
可以看出,线程轮流执行,各自打印几百个字符再进行上下文切换。两个循环“并行”运行,而不是第一个运行完了再开始第二个。
线程管理
- .Join()。可以调用Join()使一个线程等待另一个线程。它告诉操作系统暂停执行当前线程,直到另一个线程终止。
const int printNum = 1000;
static void Main(string[] args)
{
ThreadStart threadStart = doWork;
Thread thread = new Thread(threadStart);
thread.Start();
for (int j = 0; j < printNum; j++)
{
if(j==50)
{
thread.Join();
}
Console.Write("-");
}
Console.ReadLine();
}
public static void doWork()
{
for (int i =0; i < printNum; i++) {
Console.Write("+");
}
}
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++±------------------------------------------------+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++±-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
可以看出,thread线程和主线程循环执行了,当-输出超过50个后,需要等待thread线程执行完毕后,主线程才能继续执行。
- isBackGroud是否后台线程。操作系统将在进程的所有前台线程完成后终止进程。可将线程的IsBackGround属性设为true,从而将线程标记为**“后台”**线程。后台线程在主程序停止运行时也会自动停止,而前台线程在主线程停止运行后仍然执行直到线程执行完毕。
- Priority。每个线程的优先级
- ThreadState。可用Boolean属性IsAlive看一个线程是否起作用,是否完成了所有工作。更全面的线程状态可通过threadState属性访问。
生产代码不要让线程进入睡眠
在代码中要慎用Thread.Sleep()方法使当前线程进入睡眠。但是Sleep()的时间参数不能明确得出什么时间唤醒该线程,可能大于或者远远大于此时间。
生产代码不要中断线程
不要随便使用Abort()方法终止线程的运行。理想情况是在整个AppDomain或整个进程被摧毁时才中断线程。
使用线程池处理
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(doWork,"+");
for(int i = 0; i < printNum; i++)
{
Console.Write("*");
}
Thread.Sleep(1000);
Console.ReadLine();
}
public static void doWork(object state)
{
for (int i =0; i < printNum; i++) {
Console.Write(state.ToString());
}
}
要用线程池向处理器受限任务高效地分配处理器时间
避免将池中的工作者线程分配给I/O受限或长时间运行的任务,改为使用TPL。