Theread
概念
C#对线程对象的一个封装(密封类)类库
Thread实例化及调用
第一种:
只是简单的把需要线程执行的方法传递到Thread
Thread thread = new Thread(testMethod);//实例化Thread
thread.Start();//开启线程,执行方法。
第二种
使用lambda表达式
Thread thread = new Thread(s =>
{
Console.WriteLine("哈哈");
}
);
thread.Start();
第三种
在系统封装的Thread类中
我们可以看到Thread 需要接收一个ThreadStart类型的参数,而这个类型再往下看,其实就是一个无参不带返回值的委托
//ThreadStart是一个不带参数和返回值的委托
ThreadStart threadStart = () =>
{
Console.WriteLine("测试");
};
Thread threadRunStart = new Thread(threadStart);
threadRunStart.Start();
Thread常用方法介绍
等待
1判断Thread的ThreadState
ThreadState的初始状态为Unstarted(未启动)
while (thread.ThreadState != ThreadState.Stopped)
{
Thread.Sleep(200);//当前线程休息200ms
}
2 Join等待
thread.Join();//运行这句代码的线程,等待thread的完成
thread.Join(1000);//最多等待1000ms
最高优先级
优先执行,但不代表优先完成 甚至说极端情况下,
还有意外发生,不能通过这个来控制线程的执行先后顺序
thread.Priority = ThreadPriority.Highest;
前后台线程
前台线程
thread.IsBackground = false;//默认是false 前台线程,进程关闭,线程需要计算完后才退出
后台线程
thread.IsBackground = true;//关闭进程,线程退出
为了便于更加清晰的理解及运用Thread,下面做了两个简单的封装示例
需求描述:回调:启动子线程执行动作A--不阻塞--A执行完后子线程会执行动作B
#region 使用Thread 封装回调 { ThreadStart threadStart = () => this.DoSomethingLong("button3_Click"); Action actionCallBack = () => { Thread.Sleep(2000); Console.WriteLine($"This is Calllback {Thread.CurrentThread.ManagedThreadId.ToString("00")}"); }; this.MethodThread(threadStart, actionCallBack); } #endregion
//回调:启动子线程执行动作A--不阻塞--A执行完后子线程会执行动作B /// <summary> /// 思路:调用者传递一个线程执行的方法A /// 传递一个线程执行的方法B /// </summary> /// <param name="threadStart"></param> /// <param name="action"></param> public void MethodThread(ThreadStart threadStart,Action action) { //错误示例,原因:因为方法被阻塞了 //Thread thread = new Thread(threadStart); //thread.Start(); //thread.Join(); //action.Invoke(); //具体思路: //参数threadStart和action都是无参无返回值的委托 //谁先Invoke谁就先执行,等待执行完成,再执行下一个Invoke //用ThreadStart包起来,作为一个方法传递,满足先后执行,并且不会阻塞 ThreadStart _start = new ThreadStart( () => { threadStart.Invoke(); action.Invoke(); } ); new Thread(_start).Start(); }
需求描述:1 异步,非阻塞的 2 还能获取到最终计算结果
#region 使用Thread 封装有返回值异步调用 { Func<int> func = () => { Thread.Sleep(5000); return DateTime.Now.Year; }; Func<int> funcThread = this.ThreadWithReturn(func);//非阻塞 int iResult = funcThread.Invoke();//阻塞,真正需要拿到结果时。 } #endregion
/// <summary> /// 1 异步,非阻塞的 /// 2 还能获取到最终计算结果 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="func"></param> /// <returns></returns> private Func<T> ThreadWithReturn<T>(Func<T> func) { //实现思路:传递一个带返回值的泛型委托 //用ThreadStart委托包裹,然后传入线程并启动线程 //返回一个带返回值的泛型委托 T t = default(T); ThreadStart threadStart = new ThreadStart(() => { t = func.Invoke(); }); Thread thread = new Thread(threadStart); thread.Start(); //委托在不Invoke里面方法不会执行 //等到调用者Invoke这个委托时,先等线程执行完成,再返回(阻塞) return new Func<T>(() => { thread.Join(); return t; }); }