zoukankan      html  css  js  c++  java
  • 多线程---委托实现异步(一)

    一、什么是进程?

    启动一个程序就是一个进程,也就是说,一个程序就是一个进程。

    二、什么是线程?

    线程是进程的基本单元。一个进程至少包含一个线程。

    三、线程分类:线程分前台线程和后台线程

      1..前台线程:只有所有的前台线程都关闭了,程序就完全关闭了。(Thread默认是前台线程,启动后必须计算完才会退出,IsBackground=true; 设置为后台线程,会立即退出) 

      2.后台线程:只有所有的前台线程关闭了,后台线程会自动关闭。

    四、什么是同步?

    同步就是执行一段程序,从上到下按顺序依次执行。如果其中有某个方法执行时间较长,那么必须等这个方法执行完毕,才能往下执行。比如:吃饭,到饭点了,我叫小明去吃饭,但是小明说忙完了再去,然后我再哪里等他忙完了,再去吃饭。

    五、什么是异步?

    异步就是请求一个方法,如果执行时间较长,不管它等待执行的结果,而是继续往下执行,异步会有一个回调函数,把这个方法执行完成的状态返回回去。比如:吃饭,到饭点了,我叫小明去吃饭,但是小明说忙完了再去,然后我不等他了,直接去吃饭了。

    六、什么是多线程?

    一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说单个程序并发执行多个线程来完成任务。
      1.CPU运行速度太快,硬件处理速度跟不上,所有操作系统会进行时间分片管理。这样在宏观的角度来说是多线程并发,看起来统一时刻执行了不同的操作。但是从微观的角度来讲,同一时刻只能有一个线程在处理
      2.现在电脑基本上都是多核CPU的,一个CPU在同一个时刻只能运行一个线程,但是多核的CPU在同一时刻就可以运行多个线程。

    七、为什么要使用多线程?

      1.多个CPU的核可以并行工作,
      2.CPU分片,1S能处理1000份任务

    八、同步方法和异步方法的区别

      1.同步方法卡界面,主线程在忙,不空闲,异步方法不卡界面,主线程闲置,执行任务交给了子线程  

      2.同步方法执行慢,只有一个线程在执行,异步方法执行快,多个线程并发执行,多线程是资源换性能,有损资源调度

      3.同步方法有序执行,异步多线程无序执行

      

        ///同步方法
        public void SycnMethod() { Console.WriteLine("SycnMethod 方法开始执行...."); Action<string> action = Todo; for (int i = 0; i < 5; i++) { string name = $"AsycnMethod_{i}"; action.Invoke("SycnMethod"); } action.Invoke("SycnMethod"); Console.WriteLine($"SycnMethod方法,ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}"); Console.WriteLine("SycnMethod 方法结束执行...."); }
        ///异步方法
        public void AsycnMethod() { Console.WriteLine("AsycnMethod 方法开始执行...."); Action<string> action = Todo; //action.BeginInvoke("AsycnMethod", s => //{ // Console.WriteLine("回调函数....."); // Console.WriteLine(s.AsyncState); //}, "小明"); for (int i = 0; i < 5; i++) { string name = $"AsycnMethod_{i}"; action.BeginInvoke(name, null, null); } Console.WriteLine($"AsycnMethod方法,ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}"); Console.WriteLine("AsycnMethod 方法结束执行...."); }

    九、回调函数(AsyncCallback):委托调用完方法后,将后续动作通过回调参数传进去,子线程完成计算后,去调用回调委托。原理:委托在调用BeginInvoke方法后会返回一个结果为:IAsyncResult 对象,并且把这个对象作为参数传入回调函数AsyncCallback中

      1,获取回调函数的参数值:IAsyncResult.AsyncState

      2.IsCompleted 等待会卡界面,可以一边等待一边提示

      3.WaitOne 即时等待,限时等待

      4.EndInvoke  即时等待 等待某次异步调用结束

      

            public void AsyncCallBackMethod()
            {
                Console.WriteLine($"AsyncCallBackMethod 方法开始执行,ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}");
    
                Action<string> action = Todo;
    
                //AsyncCallback  带一个参数的委托
                //回调:将后续动作通过回调参数传进去,子线程完成计算后,去调用回调委托
                //action.BeginInvoke 执行的时候返回一个结果为IAsyncResult,并且把这个对象作为参数传入回调函数AsyncCallback中
                //获取回调函数的参数值:s.AsyncState
                IAsyncResult asyncResult = null;
                AsyncCallback asyncCallback = s =>
                {
                    Console.WriteLine($"{object.ReferenceEquals(s, asyncResult)}");//true
                    Console.WriteLine($"{s.AsyncState}");//name
                    Console.WriteLine($"执行成功了....ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}");
                };
                asyncResult = action.BeginInvoke("AsyncCallBackMethod", asyncCallback, "names");
                //IsCompleted 等待会卡界面,可以一边等待一边提示
                int i = 0;
                while (!asyncResult.IsCompleted)
                {
                    Thread.Sleep(40);
                    Console.WriteLine($"i={i}");
                    if (i == 100)
                    {
                        Console.WriteLine("完成100%了");
                        break;
                    }
                    else
                    {
                        i++;
                    }
                }
                Console.WriteLine("已执行完成");
                //WaitOne 即时等待,限时等待
                asyncResult.AsyncWaitHandle.WaitOne(); //直接等待任务完成
                asyncResult.AsyncWaitHandle.WaitOne(-1); //millisecondsTimeout=-1 一直等待任务完成
    
                //EndInvoke  即时等待 等待某次异步调用结束
                action.EndInvoke(asyncResult);
    
    
                asyncResult.AsyncWaitHandle.WaitOne(300); //millisecondsTimeout=300 超过300毫秒就不等待了
    
                Console.WriteLine($"AsycnMethod方法,ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}");
                Console.WriteLine($"AsycnMethod 方法结束执行,{Thread.CurrentThread.ManagedThreadId}");
            }    

    十、异步方法获取返回结果。委托调用异步方法执行后,将异步方法返回的对象作为参数传入EndInvoke方法中,获取委托执行方法中的返回值。

            public void AsyncEndInvoke()
            {
                Func<int> func = () => { return DateTime.Now.Hour; };
                IAsyncResult asyncResult = func.BeginInvoke(s =>
                {
    
                }, null);
                int result = func.EndInvoke(asyncResult);
                Console.WriteLine(result);
            }    
           private void Todo(string name)
            {
                Console.WriteLine($"Todo 方法开始执行....");
    
                long result = 0;
                for (int i = 0; i < 100000; i++)
                {
                    result += i;
                }
                Thread.Sleep(500);
                Console.WriteLine($"Todo方法执行的结果:{result},名称{name},ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}");
    
                Console.WriteLine($"Todo 方法结束执行....");
            }
    将来的你,一定会感谢现在努力的自己!
  • 相关阅读:
    Mysql学习笔记
    【转】数据库设计:物理结构设计
    primary key与unique的区别
    服务器端口
    事务 脏读、不可重复读、幻影读的分析
    数据库 count和sum区别
    c#局域网聊天软件的实现
    使用jstack分析java程序cpu占用率过高
    典型的垃圾收集器
    垃圾收集算法
  • 原文地址:https://www.cnblogs.com/GreatPerson/p/14111585.html
Copyright © 2011-2022 走看看