C# .Net学习笔记—— 异步和多线程(Async和Sync)

一、概念

进程:一个程序运行时,占用的全部计算资源的总和

线程:1、程序执行流的最小单位;任何操作都是由线程完成的

2、线程是依托于进程存在的,一个进程可以包含多个线程;

3、线程也可以有自己的计算资源

多线程:多个执行流同时运行

1、CPU太快了,分时间片-一上下文切换(加载环境--计算-一保存环境)

微观角度,一个核同一时刻只能执行一个线程;宏观的来说是多线程并发

2、多CPU多核可以独立工作

4核8线程一核是物理的核线程是指虚拟核

同步:完成计算之后,再进入下一行

异步:不会等待方法的完成,会直接进入下一行非阻塞

C#异步和多线程有什么差别

多线程就是多个thread并发;

异步是硬件式的异步

异步多线程-thread pool task

二、同步异步简单案例

cs 复制代码
 private void buttonSync_Click(object sender, EventArgs e)
        {
            Log.Info($"S Start {Thread.CurrentThread.ManagedThreadId}");
            int j = 3;
            int k = 5;
            int m = j + k;
            for (int i = 0; i < 5; i++)
            {
                string name = string.Format($"**********S{i}*************");
                this.DoSomethingLong(name);
            }
            Log.Info($"S End");
        }

        private void buttonAsync_Click(object sender, EventArgs e)
        {
            Log.Info($"\nA Start {Thread.CurrentThread.ManagedThreadId}");
            Action<string> action = this.DoSomethingLong;
            for (int i = 0; i < 5; i++)
            {
                string name = string.Format($"**********A{i}*************");
                action.BeginInvoke(name, null, null);
            }
            Log.Info($"A End");
        }

        private void DoSomethingLong(string name)
        {
            Log.Info($"DoSomethingLong Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {name} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
            long result = 0;
            for (int i = 0; i < 100000000; i++)
            {
                result += i;
            }
            Thread.Sleep(2000);
            Log.Info($"DoSomethingLong End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {name} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
        }

同步:

异步:

从打印结果来看也能反映出,

同步:1、完成计算之后,再进入下一行。

2、同步方法卡界面,主(UI)线程忙于计算。

3、同步方法慢,只有一个线程干活
异步:1、不会等待方法的完成,会直接进入下一行非阻塞。

2、异步多线程方法不卡界面,主线程完事,计算任务交给子线程在做。

3、异步多线程方法快,因为多个线程并发运算

4、异步并不是线性增长,而是资源换时间,多线程也有管理成本

5、提升用户体验

6、并不是越多越好

7、最好是多个独立任务同时进行的使用

异步等待方式1:异步回调:

cs 复制代码
        private void buttonAysncCallback_Click(object sender, EventArgs e)
        {
            Log.Info($"DoSomethingLong Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
            Action<string> action = this.DoSomethingLong;

            AsyncCallback callback = ia => Log.Info($"计算完成。{Thread.CurrentThread.ManagedThreadId.ToString("00")}  {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
            action.BeginInvoke("AysncCallBack", callback, null);
            Log.Info($"DoSomethingLong End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
        }

从结果来看,异步回调action.BeginInvoke()可以得到一个AsyncCallBack,然后这个callBack再执行的委托。这样可以有效的控制我们线程的次序。

缺点:我想要全部计算都完成了再给用户返回结果,这种方法实现不了

异步等待方式2:线程等待

cs 复制代码
asyncResult.AsyncWaitHandle.WaitOne(); //等待任务完成
asyncResult.AsyncWaitHandle.WaitOne(); //等待任务完成
asyncResult.AsyncWaitHandle.WaitOne(1000); //等待;但是最多等待1000ns

异步等待方式3: EndInvoke()

cs 复制代码
        private void buttonTest_Click(object sender, EventArgs e)
        {
            Func<int> func = () =>
            {
                Thread.Sleep(2000);
                return DateTime.Now.Day;
            };
            Console.WriteLine($"func.Invoke()={func.Invoke()}");

            IAsyncResult asyncResult = func.BeginInvoke(r =>
            {
                Console.WriteLine(r.AsyncState);
            }, "哈啊哈哈");
            Console.WriteLine($"func.EndInvoke(asyncResult) = {func.EndInvoke(asyncResult)}");
        }
相关推荐
键盘歌唱家20 分钟前
Spring AI 入门分享:它和“直接调 API“到底差在哪
java·人工智能·spring
MartinYeung523 分钟前
[论文学习]大型语言模型(LLM)安全与隐私-基于善、恶、丑的深度分析
学习·安全·语言模型
什仙25 分钟前
Mathcad Prime 的教程资料
学习·工具
宸丶一1 小时前
Day 10:LangGraph - Agent 的图执行引擎
java·windows·python
hikktn1 小时前
Excel 导出 OOM 预防实战:30 万行从堆溢出到 50MB 的演进
java·excel·easyexcel
风味蘑菇干1 小时前
WTomcat服务器
java·服务器
hhcgchpspk1 小时前
汇编语言传递数据和地址的误区
汇编·笔记·nasm·masm
智者知已应修善业1 小时前
【51单片机2个外部中断显示中断历时,初始化8左移3位共阳数码管】2024-6-6
c++·经验分享·笔记·算法·51单片机
燕-孑1 小时前
tomcat详解(基础到高级生产)
java·tomcat
nashane1 小时前
HarmonyOS 6学习:深入解析冷启动中的ArkCompiler
学习·华为·harmonyos