异步多线程(二)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判断ThreadThreadState

   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;
            });
        }

猜你喜欢

转载自www.cnblogs.com/JohnTang/p/10987485.html
今日推荐