异步多线程Thread
Posted johntang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步多线程Thread相关的知识,希望对你有一定的参考价值。
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; );
以上是关于异步多线程Thread的主要内容,如果未能解决你的问题,请参考以下文章
在控制台应用程序中,为啥在等待的异步任务中使用同步阻塞代码 (Thread.Sleep(..)) 的行为类似于多线程? [复制]
异步和多线程,委托异步调用,Thread,ThreadPool,Task,Parallel,CancellationTokenSource