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

这篇具有很好参考价值的文章主要介绍了C# .Net学习笔记—— 异步和多线程(Thread)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、简单案例

      private void buttonThreads_Click(object sender, EventArgs e)
        {
            Log.Info($"btnThread_Click_Start {Thread.CurrentThread.ManagedThreadId}");
            ThreadStart threadStart = () => this.DoSomethingLong("btnThread_Start");
            Thread thread = new Thread(threadStart);
            thread.Start();
            Log.Info($"btnThread_Click_End {Thread.CurrentThread.ManagedThreadId}");
        }

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

C# .Net学习笔记—— 异步和多线程(Thread),c#,.net,学习

 注意:现在不建议使用thread.Suspend();//线程挂起

                                 和thread.Resum();   //唤醒线程

thread.Abort(); //销毁,方法是抛异常,也不建议使用

 二、常用API介绍

1、Join 线程等待
thread.Join(500);//最多等待500毫秒
thread.Join();   //当前线程等待thread完成
2、thread.ThreadState; //线程状态
3、thread.IsBackground;

(i)默认是前台线程,启动之后一定要完成任务的,阻止进程退出。

(ii)如果使用后台线程,只要进程退出了线程也就退出了,现在一般都建议使用后台线程,因为不会卡界面。

4、thread.Priority;  

(i)线程优先级,可以设置5个等级  CPU会优先执行ThreadPriority。

(ii)但是不代表它会最先完成

二、Thread的问题

线程池--享元模式--数据库连接池

1、thread提供了太多的API

2、无限使用线程,需要加以限制

3、重用线程,避免重复的创建和销毁

三、线程池

       private void buttonQueue_Click(object sender, EventArgs e)
        {
            Log.Info($"DoSomethingLong Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
            ThreadPool.QueueUserWorkItem(t => this.DoSomethingLong("btnThreadPool_Click"));
            Log.Info($"DoSomethingLong End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
        }

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

C# .Net学习笔记—— 异步和多线程(Thread),c#,.net,学习

 1、手动限制线程池内的数量
        private void buttonQueue_Click(object sender, EventArgs e)
        {
            Log.Info($"DoSomethingLong Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
            ThreadPool.QueueUserWorkItem(t => this.DoSomethingLong("btnThreadPool_Click"));

            {
                ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads);
                Log.Info($"线程池中辅助线程最大数目={workerThreads} 线程池中异步IO线程的最大数目={completionPortThreads}");
            }
            {
                ThreadPool.GetMinThreads(out int workerThreads, out int completionPortThreads);
                Log.Info($"线程池中辅助线程最小数目={workerThreads} 线程池中异步IO线程的最小数目={completionPortThreads}");
            }

            ThreadPool.SetMaxThreads(16, 16);
            ThreadPool.SetMinThreads(8, 8);

            {
                ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads);
                Log.Info($"线程池中辅助线程最大数目={workerThreads} 线程池中异步IO线程的最大数目={completionPortThreads}");
            }
            {
                ThreadPool.GetMinThreads(out int workerThreads, out int completionPortThreads);
                Log.Info($"线程池中辅助线程最小数目={workerThreads} 线程池中异步IO线程的最小数目={completionPortThreads}");
            }

            Log.Info($"DoSomethingLong End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
        }

C# .Net学习笔记—— 异步和多线程(Thread),c#,.net,学习

 ThreadPool啥也没有,不能控制线程的开始,暂停,恢复等功能

四、线程池等待 

1、类 包含了一个bool属性
     初始化为false -- WaitOne 等待 -- Set -- true--WaitOne直接过去
     true--WaitOne直接过去--Reset -- false -- WaitOne等待

        private void buttonQueue_Click(object sender, EventArgs e)
        {
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            ThreadPool.QueueUserWorkItem(t =>
            {
                this.DoSomethingLong("btnThreadPool_Click");
                manualResetEvent.Set();
            });
            manualResetEvent.WaitOne();
        }

C# .Net学习笔记—— 异步和多线程(Thread),c#,.net,学习

五、线程池阻塞(死锁)

private void button小案例_Click(object sender, EventArgs e)
        {
            {
                ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads);
                Console.WriteLine(workerThreads + " " + completionPortThreads);
            }

            ThreadPool.SetMaxThreads(20, 20);
            ThreadPool.SetMinThreads(8, 8);

            
            {
                ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads);
                Console.WriteLine(workerThreads + " " + completionPortThreads);
            }

            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            for (int i = 0; i < 28; i++)
            {
                int k = i;
                ThreadPool.QueueUserWorkItem(t =>
                {
                    Console.WriteLine(k);
                    if (k < 20) 
                    {
                        manualResetEvent.WaitOne();
                    }
                    else 
                    {
                        manualResetEvent.Set();
                    }
                });
            }
            if (manualResetEvent.WaitOne()) 
            {
                Console.WriteLine("没有死锁");
            }
        }

这段代码里我限定了线程池里边只有20个线程,而我for循环里调用了超过20个,所以产生了线程死锁问题。

原因:我们在使用阻塞方法的时候没有把线程Set回去文章来源地址https://www.toymoban.com/news/detail-781970.html

private void buttonQueue_Click(object sender, EventArgs e)
        {
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            ThreadPool.QueueUserWorkItem(t =>
            {
                this.DoSomethingLong("btnThreadPool_Click");
                //这里应该Set回去
                manualResetEvent.Set();
            });
            manualResetEvent.WaitOne();
        }

到了这里,关于C# .Net学习笔记—— 异步和多线程(Thread)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 每个.NET开发都应掌握的C#多线程知识点

    上篇文章讲述了C#特性(Attribute)知识点,本文将介绍多线程的知识点。多线程编程是现代软件开发中的重要组成部分,它能够充分利用多核处理器,提高应用程序的性能和响应性。C#作为.NET开发的主要语言,提供了强大的多线程支持。本文将介绍C#多线程知识点,帮助.NET开

    2024年02月05日
    浏览(42)
  • ORB-SLAM2学习笔记7之System主类和多线程

    ORB-SLAM2是一种基于特征的视觉 SLAM ( Simultaneous Localization and Mapping )系统,它能够从单个、双目或 RBGD 相机的输入中实时地同时定位相机的位置,并构建环境的三维地图。 ORB-SLAM2 是在ORB-SLAM的基础上进行改进和扩展的版本。

    2024年02月12日
    浏览(41)
  • 【文末送书】Python高并发编程:探索异步IO和多线程并发

    欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。搜索关注公粽号 《机器和智能》 发送“刷题宝

    2024年02月15日
    浏览(32)
  • C#核心笔记——(一)C#和.NET Framework

    C#是一种通用的,类型安全的面向对象编程语言。其目标是提高程序员生产力。 C#实现了丰富的面向对象范式,包括封装、继承、多态。 C#面向对象特性包括: 统一的类型系统 类与接口 属性、方法、事件 C#支持纯函数模式 C#是一门类型安全的语言。例如:C#不允许将字符串类

    2024年02月08日
    浏览(47)
  • c# 学习笔记 - 异步编程

    1.1 简单介绍   异步编程官方参考文档:异步编程     1.2 async/await 使用   细节注意 async 用来修饰方法,表示这个方法可以成为一个异步方法,但是如果内部没有搭配使用 await 的话其作用还是等效于一个同步方法 await 必须用于在 async 修饰的异步方法内使用,

    2024年01月18日
    浏览(40)
  • WPF C# .NET7 基础学习

    学习视频地址:https://www.bilibili.com/video/BV1hx4y1G7C6?p=3vd_source=986db470823ebc16fe0b3d235addf050 开发工具:Visual Studio 2022 Community 基础框架:.Net 6.0 下载创建过程略 .Net和.Framework 区别是Net是依赖项,Framework是引用 1.定义一个命名空间, 最常用 不只包括using namespace,还用开头使用的usin

    2024年02月10日
    浏览(34)
  • .NET 6和.Net Core学习笔记:什么是.NET Core

    NET是开发平台 .NET是 .NET Framework、.NET Core、Xamarin/Mono的统称。 .NET Framework:近20年历史,.NET简称的最早拥有者,用于开发Windows程序。 Xamarin/Mono主要做移动开发:Xamarin、Unity。Mono也能做Web等跨平台开发,但主要专注移动端。 .NET Core:免费、跨平台、开源。 跨平台:程序可以运

    2024年02月08日
    浏览(27)
  • .NET 6和.Net Core学习笔记:.NET Core的重要问题

    什么是C#? .NET中主要的开发语言。 推荐C#书籍:《C#图解教程》,《C#入门经典》 尽管绝大部分用法都没变,但是.NET Core不是 .NET Framework的升级版,无法直接升级 绝大部分用法没有变,但又有部分是不能使用的。 又被微软坑了? .NET Framework白学了? 软件开发界的技术是不断

    2024年02月04日
    浏览(83)
  • C#基础--线程Thread和线程池ThreadPool

    1. 开启一个线程 ThreadStart 是属于System.Threading 中的一个内置委托 ParameterizedThreadStart 是属于System.Threading 中的一个内置委托 2. 暂停/恢复线程 无法实时的去 “暂停 ” 或者 “恢复” 线程,因为线程是由系统调度执行的,而且中间存在一个延时现象,不可能直接帮你执行 3. 终结

    2024年02月16日
    浏览(22)
  • C#.Net学习笔记——CLR核心机制

    (1)C(Common) L(Language) R(Runtime) IL 的运行环境 (2) 从下图可以看到,我们的计算机会先把我们写的语言,编写成 IL 语言,再给计算机去读取。为什么我们不直接把我们的语言编写成计算机能够读取的?主要是考虑到我们计算机的不同,比如32位和64位,他们接收到计算

    2024年01月22日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包