4:c#教程-多线程
4.1 多线程开发
线程与线程函数
把分割出来的工作任务封装为一个函数,由线程负责执行。线程的运行过程体现为线程函数的运行过程。
4.1.1 多线程开发基础知识
- 线程对象的创建与运行
MyClass obj= new MyClass();
//原始写法
Thread th1 = new Thread(new ThreadStart(MyClass.StaticMethod)); //委托-静态方法
Thread th2 = new Thread(new ThreadStart(obj.InstanceMethod))// 委托-实例化方法
//简化写法
Thread th3 = new Thread(MyClass.StaticMethod);
Thread th4 = new Thread(obj.InstanceMethod);
//Lambda表达式
Thread th5 = new Thread(()=>{
//线程函数
});
- 多线程基本方法
th.start() // 执行线程
Thread.CurrentThread //可获取负责执行当前函数的线程对象引用
Thread.ManagedThreadID // 每个线程都有一个ID
Thread.Sleep(number) //当前线程暂停,进入阻塞状态,可能影响性能。number为时间,单位是毫秒
Thread.SpinSLeep(number) //让CPU空转,但线程状态不改变(不进入阻塞状态),只适合暂停很短时间时使用,小于1s
th.Abort() //提前终止线程,一般不用
th.IsBackground //设置属性为true的线程称为背景线程;背景线程在主线程结束时自动中断执行;默认为False,即“前台线程”,CLR会等待所有前台线程结束后才会结束整个线程。
th.Join() //把线程嵌入到当值执行的线程中,当前线程会等待th线程执行完毕后再继续(需先th.start()),不推荐使用,容易造成死锁。Join就是插队的意思
//线程状态: 托管线程 不与 操作系统的原始线程 一一对应
- 线程终止时,如何清理?
public void SomeLongTask(){
try{
System.Console.WriteLine("辅助线程开始。。。");
}catch(ThreadAbortException e){ //需要捕获线程终止异常
System.Console.WriteLine("辅助线程被提前终端:{0}",e.Message);
Thread.ResetAbort(); //不加此句,CLR会再次抛出这个异常,从而导致函数最后函数最后一句代码不会执行
}finally{
System.Console.WriteLine("此时完成清理辅助线程占用的资源工作");
}
System.Console.WriteLine("辅助线程结束"); //不加 ResetAbort() 不会执行到此句
}
4.1.2 多线程开发基本技巧
public Thread(ThreadStart start); //ThreadStart是委托,接收的函数不能有参数和返回值
如何接收带参数的线程函数?
- 外套函数(缺点:1.字段共有,违背面向对象的“封装”原则;2.如果有多个方法,则字段数目爆炸)
class MyThread{
//带参数和返回值的函数
public long SomeFunc(int xx, int yy){
return xx + yy;
}
//将SomeFunc参数和返回值外化为类的共有字段
public int x;
public int y;
public long returnValue;
//供多线程调用的“外套”番薯
public void ThreadMethod(){
returnValue = SomeFunc(x,y);
}
}
//使用时,先设置x,y的值,再调用线程,完成后获取returnValue
MyThread obj = new MyThread(){
x = 100, y = 120
}
Thread th = new Thread(MyThread.ThreadMethod);
th.Start();
th.Join();
Console.WriteLine(obj.returnValue);
- 使用ParameterizedThreadStart委托(只接收一个object参数,需要创建参数辅助类ThreadMethodHelper)
//单参数无返回值时,直接改写函数
void Func(int x){
//...
}
//==>
static void Func(object x){
int argu = Convert.ToInt32(x);
//...
}
Thread th = new Thread(new ParameterizedThreadStart(Func));
th.Start();
//多参数有返回值,使用参数辅助类
long SomeFunc(int x,int y ){
long ret = 0;
// ...
return ret;
}
//==>
class ThreadMethodHelper{
//线程输入参数
public int x;
public int y;
//函数返回值
public long returnValue;
}
public void SomeFunc(object argu){
int x = (argu as ThreadMethodHelper).x;
int y = (argu as ThreadMethodHelper).y;
//...
returnvalue = x +y ;
(argu as ThreadMethodHelper).returnValue = returnvalue
}
//使用
var argu = new ThreadMethodHelper();
argu.x = 100; argu.y = 120;
Thread th = new Thread(new ParameterizedThreadStart(SomeFunc));
th.Start(argu);
th.Join();
Console.WriteLine(argu.returnValue); //取回线程结果

浙公网安备 33010602011771号