/* github */
随笔 - 44  文章 - 0  评论 - 20  阅读 - 79344

多线程系列(二)之Thread类

在上一遍文章中讲到多线程基础,在此篇文章中我们来学习C#里面Thread类。Thread类是在.net framework1.0版本中推出的API。如果对线程的概念还不太清楚的小伙伴请阅读我的上一遍文章:多线程系列(一),多线程基础

在本篇文章中新开启一个线程来异步调用的方法代码为:

复制代码
        private void DoSomeThing(string btnName) {
            Console.WriteLine($"{btnName} 开始,当前线程id:{Thread.CurrentThread.ManagedThreadId}");
            long lResult = 0;
            for (long i = 0; i < 1_00_000_000; i++)
            {
                lResult += i;
            }
            Console.WriteLine($"{btnName} 结束,当前线程id:{Thread.CurrentThread.ManagedThreadId}");
        }
复制代码

如何使用Thread来开启一个新的线程?

方式一:基于委托ParameterizedThreadStart

                ParameterizedThreadStart method = o => this.DoSomeThing("btnThread_Click");
                Thread thread = new Thread(method);
                thread.Start();//开启线程,执行委托的内容

方式二:基于委托ThreadStart

                ThreadStart method = () =>
                {
                    Thread.Sleep(3000);
                    this.DoSomeThing("btnThread_Click");
                };
                Thread thread = new Thread(method);
                thread.Start();//开启线程,执行委托的内容

线程的暂停(挂起)、休眠、继续、终止

thread.Suspend();//暂停,挂起线程,如果线程已经挂起,则不起作用

thread.Resume();//继续已经挂起的线程

thread.Abort();//终止线程,会在当前线程中抛出一个异常引发线程停止,不过会有延迟,因为线程属于计算机资源,程序想停下线程,只能向操作系统通知(抛异常),不一定真的能停下来

Thread.ResetAbort();//终止当前线程,取消当前线程的所有请求,只能终止一次

Thread.Sleep();//使当前线程休眠多少毫秒再继续执行

线程等待

方式一:通过thread.ThreadState获取当前线程的状态

                while (thread.ThreadState != System.Threading.ThreadState.Stopped)
                {
                    Thread.Sleep(500);
                    Console.WriteLine($"线程_{ thread.ManagedThreadId.ToString("00")}_正在运行中...");
                }

方式二:通过Join等待

thread.Join(); //等待线程thread执行完毕

thread.Join(5000); //限时等待,最多等待5000毫秒

线程的优先级

thread.Priority = ThreadPriority.Highest;

设置线程的优先级为最高优先级:优先执行,但不代表优先完成,甚至说极端情况下,还有意外发生,不能通过这个来控制线程的执行先后顺序

前台线程与后台线程

thread.IsBackground = false;//默认是false 前台线程,进程关闭,线程需要计算完后才退出

thread.IsBackground = true; //关闭进程,线程退出

线程的回调

我们希望某个线程在执行某个动作之后触发另一个动作,下面是我基于Thread封装的线程回调函数

复制代码
        /// <summary>
        /// 基于thread封装一个回调,启动子线程执行动作A--不阻塞--A执行完后子线程会执行动作B,不阻塞
        /// </summary>
        /// <param name="method">动作A</param>
        /// <param name="action">动作B</param>
        private void ThreadWithCallBack(ThreadStart method,Action action)
        {
            ThreadStart threadStart = () =>
            {
                method.Invoke();
                action.Invoke();
            };
            new Thread(threadStart).Start();
        }
复制代码

调用测试代码:

复制代码
        ThreadStart method = () =>
        {
            this.DoSomeThing("btnThread_Click");
        };
        Action actionCallBack = () =>
        {
            Console.WriteLine("method 的回调");
        };
        this.ThreadWithCallBack(method, actionCallBack);
复制代码

获取子线程的返回值

下面是我基于Thread封装的获取子线程的返回值函数

复制代码
        T t = default(T);
        ThreadStart threadStart = () =>
        {
            t = func.Invoke();
        };
        Thread thread = new Thread(threadStart);
        thread.Start();

        return new Func<T>(() => {
            thread.Join();
            return t;
        });
复制代码

调用测试代码

        Func<int> func = () => {
            return DateTime.Now.Hour;
        };
        Func<int> funcThread = this.ThreadWithReturn<int>(func);//非阻塞
        int res =  funcThread.Invoke();//阻塞

 在下一篇中,会继续讲到线程池

posted on   王精灵  阅读(483)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示