• 异步多线程(二)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;
                });
            }
  • 相关阅读:
    一个实现编译次数记录的jsfl
    特殊的RSS图标设置,您可以免费使用
    jquery实现的视差滚动教程(视差大背景效果)
    40个免费的wordpress主题推荐
    php+mysql方便的查询
    jQuery 简单实现select二级联动
    我对Oracle的刷未提交数据到文件的学习体会
    dbms_output.put_line的小例子
    isqlplus 的 define 与 pl/sql 的 &
    PLSQL 的 for循环的小例子
  • 原文地址:https://www.cnblogs.com/JohnTang/p/10987485.html
Copyright © 2020-2023  润新知