志在指尖
用双手敲打未来

C#线程学习线程基础

一、线程的介绍
进程(Process)是应用程序的实例要运用的资源的一个调集,每个应用程序都在各自的进程中运转来确保应用程序不受其他应用程序的影响。
线程是进程中根本履行单元,一个进程中能够包括多个线程。在进程进口履行的第一个线程是一个进程的主线程,在.NET应用程序中,都是以Main()办法
作为程序的进口(线程是进程的履行单元,进程是线程的一个容器)。
二、线程调度和优先级
Windows之所以被称为抢占式多线程操作体系,是因为线程能够在恣意时刻被抢占,并调度另一个线程。
每个线程都分配了从0~31的一个优先级,体系首先把高优先级的线程分配给CPU履行。
Windows支撑7个相对线程优先级:Idle、Lowest、BelowNormal、Normal、AboveNormal、Highest和Time-Critical。Normal是默许的线程优先级,
然而在程序中能够经过设置Thread的Priority属性来改动线程的优先级,它的类型为ThreadPriority枚举类型:Lowest、BelowNormal、Normal、AboveNormal
和Highest,CLR为自己保留了Idle和Time-Critical优先级。
枚举值列表如下:
成员名称阐明
Lowest能够将Thread置于其他优先级线程之后。
BelowNormal能够将Thread置于Normal优先级线程之后Lowest优先级线程之前。
Normal
能够将Thread置于AboveNormal优先级线程之后BelowNormal优先级线程之前。
默许情况下,线程置于Normal优先级。
AboveNormal能够将Thread置于Highest优先级线程之后Normal优先级线程之前。
Highest能够将Thread置于其他优先级线程之前。c#
三、前台线程和后台线程
在.NET中线程分为前台线程和后台线程:
I、主线程是程序开始时就履行的,假设你需求再创立线程,那么创立的线程就是这个主线程的子线程,它是前台线程。
II、子线程能够是前台线程也能够是后台线程。
III、前台线程必须悉数履行完,即使主线程关闭掉,这时进程仍然存活。
IV、当所有前台线程停止运转时,CLR会强制完毕仍在运转的任何后台线程,这些后台线程直接被停止,不会抛出反常。
V、前台线程与后台线程仅有的区别是后台线程不会阻挠进程停止,能够在任何时分将前台线程修改为后台线程。
staticvoidMain(string[]args)
{
ThreadType();
}//////前台线程与后台线程///privatestaticvoidThreadType()
{//创立一个新线程(默许为前台线程)ThreadbackThread=newThread(Worker)
{//将线程更改为后台线程IsBackground=true};//经过Start办法启动线程backThread.Start();//假设backThread是前台线程,则应用程序5秒后才停止。//假设backThread是后台线程,则应用程序当即停止。Console.WriteLine(“It’sfrommainthread.”);//Console.Read();}privatestaticvoidWorker()
{//歇息5秒Thread.Sleep(5000);
Console.WriteLine(“It’sfromworkerthread.”);
}
假设保留IsBackground=true;但又想持续履行Worker()办法的话,能够调用Thread.Join()办法来完成。Join()办法能确保主线程(前台线程)在异步线程
Thread(后台线程)运转完毕后才会运转。
staticvoidMain(string[]args)
{
ThreadStatusChange();
}//////线程状况之间的转换///privatestaticvoidThreadStatusChange()
{//创立一个新线程(默许为前台线程)ThreadbackThread=newThread(Worker)
{//将线程更改为后台线程IsBackground=true};//经过Start办法启动线程backThread.Start();//Join()办法能确保主线程(前台线程)在异步线程Thread(后台线程)运转完毕后才会运转backThread.Join();
Console.WriteLine(“It’sfrommainthread.”);
Console.Read();
}privatestaticvoidWorker()
{//歇息5秒Thread.Sleep(5000);
Console.WriteLine(“It’sfromworkerthread.”);
}
运转成果如下:
四、Suspend和Resume办法
这两个办法在.NETFramework1.0的时分就支撑的办法,他们分别能够挂起线程及康复挂起的线程,但在.NETFramework2.0以后的版本中这两个办法都过时了。
MSDN的解说是这样:
警告:
不要运用Suspend和Resume办法来同步线程的活动。您无法知道挂起线程时它正在履行什么代码。假设您在安全权限评估期间挂起持有锁的线程,
则AppDomain中的其他线程或许被阻止。假设您在线程正在履行类结构函数时挂起它,则AppDomain中测验运用该类的其他线程将被阻挠。这样很容易发作死锁。
staticvoidMain(string[]args)
{
ThreadResume();
}//////线程康复///privatestaticvoidThreadResume()
{
Threadthread=newThread(ThreadSuspend)
{
Name=”Thread1″};
thread.Start();
Thread.Sleep(2000);
Console.WriteLine(“MainThreadisrunning.”);//线程康复thread.Resume();
Console.Read();
}//////线程挂起///privatestaticvoidThreadSuspend()
{
Console.WriteLine(“Thread:{0}hasbeensuspended.”,Thread.CurrentThread.Name);//将当时线程挂起Thread.CurrentThread.Suspend();
Console.WriteLine(“Thread:{0}hasbeenresumed.”,Thread.CurrentThread.Name);
}
在上面这段代码中Thread1线程是在主线程中康复的,但当主线程发作反常时,这时分Thread1就会一向处于挂起状况,此刻Thread1所运用的资源就不能开释
(除非强制停止进程),当其它的线程需求运用这快资源的时分,很有或许就会发作死锁现象。
上面一段代码还存在一个危险,假设把Thread.Sleep(2000);这段代码注释一下:
staticvoidMain(string[]args)
{
ThreadResume();
}//////线程康复///privatestaticvoidThreadResume()
{
Threadthread=newThread(ThreadSuspend)
{
Name=”Thread1″};
thread.Start();//Thread.Sleep(2000);Console.WriteLine(“MainThreadisrunning.”);//线程康复thread.Resume();
Console.Read();
}//////线程挂起///privatestaticvoidThreadSuspend()
{
Console.WriteLine(“Thread:{0}hasbeensuspended.”,Thread.CurrentThread.Name);//将当时线程挂起Thread.CurrentThread.Suspend();
Console.WriteLine(“Thread:{0}hasbeenresumed.”,Thread.CurrentThread.Name);
}
这个时分,主线程因为跑(运转)得太快,做完自己的事情去唤醒Thread1时,此刻Thread1还没有挂起,而此刻唤醒Thread1就会出现反常了。
五、Abort和Interrupt办法
Abort办法和Interrupt都是用来停止线程的,但是两者仍是有区别的:
1、它们抛出的反常不一样:Abort办法抛出的反常是ThreadAbortException,Interrupt抛出的反常为ThreadInterruptedException。
2、调用Interrupt办法的线程之后能够被唤醒,然而调用Abort办法的线程就直接被停止不能被唤醒了。
下面演示Abort办法的运用:
staticvoidMain(string[]args)
{//ThreadType();//ThreadStatusChange();//ThreadResume();ThreadAbort();
}//////线程中止(不可再唤醒)///privatestaticvoidThreadAbort()
{
ThreadthreadAbort=newThread(AbortMethod)
{
Name=”ThreadAbort”};
threadAbort.Start();
Thread.Sleep(1000);try{
threadAbort.Abort();
}catch{
Console.WriteLine(“1->{0}exceptionhappeninmainthread.”,Thread.CurrentThread.Name);
Console.WriteLine(“2->{0}statusis:{1}inmainthread.”,Thread.CurrentThread.Name,Thread.CurrentThread.ThreadState);
}finally{
Console.WriteLine(“3->{0}statusis:{1}inmainthread.”,threadAbort.Name,threadAbort.ThreadState);
}
threadAbort.Join();
Console.WriteLine(“4->{0}statusis:{1}”,threadAbort.Name,threadAbort.ThreadState);
Console.Read();
}//////Abort办法///privatestaticvoidAbortMethod()
{try{
Thread.Sleep(5000);
}catch(Exceptione)
{
Console.WriteLine(e.GetType().Name);
Console.WriteLine(“5->{0}exceptionhappeninabortthread.”,Thread.CurrentThread.Name);
Console.WriteLine(“6->{0}statusis:{1}inabortthread.”,Thread.CurrentThread.Name,Thread.CurrentThread.ThreadState);
}finally{
Console.WriteLine(“7->{0}statusis:{1}inabortthread.”,Thread.CurrentThread.Name,Thread.CurrentThread.ThreadState);
}
}
运转成果如下:
从运转成果能够看出,调用Abort办法的线程引发的反常类型为ThreadAbortException,另外反常只会在调用Abort办法的线程中发作,而不会在主线程中抛出,
其次调用Abort办法后线程的状况不是当即改动为Aborted状况,而是从AbortRequested->Aborted。
六、简单线程的运用
其实在上面介绍前台线程和后台线程的时分已经经过ThreadStart托付创立一个线程了,此刻已经完成了一个多线程的一个过程。
下面经过ParameterizedThreadStart托付的方法来完成多线程:
staticvoidMain(string[]args)
{ThreadTypeUseParameterized();
}//////前台线程与后台线程(运用ParameterizedThreadStart托付的方法来完成多线程)///privatestaticvoidThreadTypeUseParameterized()
{//创立一个新线程(默许为前台线程)ThreadbackThread=newThread(newParameterizedThreadStart(Worker1));//经过Start办法启动线程backThread.Start(123);//假设backThread是前台线程,则应用程序5秒后才停止。//假设backThread是后台线程,则应用程序当即停止。Console.WriteLine(“It’sfrommainthread.”);
}privatestaticvoidWorker1(objectparameter)
{//歇息5秒Thread.Sleep(5000);
Console.WriteLine(parameter+”isfromworker1thread.”);
Console.Read();
}

未经允许不得转载:IT技术网站 » C#线程学习线程基础
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载