多线程---委托实现异步(一)

一、什么是进程?

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

二、什么是线程?

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

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

  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 方法结束执行....");
        }
将来的你,一定会感谢现在努力的自己!
原文地址:https://www.cnblogs.com/GreatPerson/p/14111585.html