[原创][1]探究C#多线程开发细节-“Thread类的简单使用“

[简介]

常用网名: 猪头三

出生日期: 1981.XX.XX
QQ: 643439947

个人网站: 80x86汇编小站 https://www.x86asm.org

编程生涯: 2001年~至今[共22年]

职业生涯: 20年

开发语言: C/C++、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python

开发工具: Visual Studio、Delphi、XCode、Eclipse、C++ Builder

技能种类: 逆向 驱动 磁盘 文件

研发领域: Windows应用软件安全/Windows系统内核安全/Windows系统磁盘数据安全/macOS应用软件安全

项目经历: 磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测

[序言]

随着.NET 8和C# 12的同时发布, 让我意识到, 是时候要更新自身陈旧的C#语言基础了. 目前先定下一个小目标: 完成C#下的多线程开发新技术的学习. 因此就有该系列文章. 对于编程经验的人来说, 优先巩固多线程的相关新知识点是最好的选择.

[首先要明白一个重要理论: 后台线程与UI线程是2个不同线程, 要让它们两者之间能顺利的进行数据交互, 需要遵守编程规范]

(这个重要的理论是贯穿该系列文章的, 所以优先在这里说明) Windows操作系统中的UI元素(例如在WinForms或WPF应用程序中的窗体、按钮、文本框等)是由UI线程负责管理和更新的. 这个UI线程也被称为消息循环线程或主线程, 它负责处理用户交互、绘制界面以及响应操作系统发送的消息等任务. 如果有其它后台线程(非UI的)直接访问或更新UI元素可能导致潜在的线程安全问题和不可预测的行为,比如会触发线程冲突和跨线程访问UI的异常. 这是因为后台线程(非UI的)和UI线程是相互独立的, 不能随便跨越访问. 为了解决这个问题, 如果用C#编写多线程的话, 自带的线程库本身都会提供安全的方法让开发者进行调用. 从而解决后台线程与UI线程交互的问题.

[正式开启C#版本的最简单的多线程开发]
1> 启动Visual Studio Enterprise 2022版本
2> 建立一个C# Windows窗体应用(.NET Framework).
3> 模仿下面的代码, 抄写到你建立的项目中

cs 复制代码
    public partial class Form_Main : Form
    {
        public Form_Main()
        {
            InitializeComponent();
        }

        private void mpr_pro_UpdateText(string str_param_Text)
        {
            // 在界面上显示线程运行信息
            lb_ShowInfo.Text = str_param_Text;
        }

        private void Bn_StartThread_Click(object sender, EventArgs e)
        {
            // 启动一个新线程
            Thread class_NewThread = new Thread(() =>
            {

                // 切换至UI线程(界面线程)上更新文本框
                this.Invoke((MethodInvoker)delegate {

                    mpr_pro_UpdateText("Hello World 线程已启动并进入工作状态...");

                });

                // 用休眠函数, 模拟一些耗时操作
                Thread.Sleep(3000);

                // 切换至UI线程(界面线程)上更新文本框
                this.Invoke((MethodInvoker)delegate {

                    mpr_pro_UpdateText("Hello World 线程运行完毕.");

                });
            });

            class_NewThread.Start();
        }
    }

代码解释: 窗体上有一个按钮, 然后单击按钮之后, 会创建的一个线程class_NewThread, 该线程启动并运行时, 会先休眠1秒钟, 然后调用this.Invoke方法处理界面更新的问题. 作用就是: 在界面显示一个字符"Hello World 线程已经启动."

[重要的核心理解]
1> 使用Thread类new()出一个新线程
2> 通过Start()把新线程启动起来
3> 新线程通过调用this.Invoke()->mpr_pro_UpdateText()来更新界面.

[针对this.Invoke()重点理解]

Invoke()方法允许你将更新UI元素的操作委托给UI线程去执行, 它通过在UI线程上执行特定的委托或方法来确保在正确的线程上下文中更新UI元素. 这种机制实际上是把将要执行的操作加入到UI线程的消息队列中, 然后由UI线程按照队列的顺序执行来实现的. 这样可以避免直接从后台线程(非UI的)访问UI元素所带来的潜在问题并确保安全地更新界面数据.

[总结]

可能很多人看到这篇文章感觉很简单, 其实代码有很多细节, 需要慢慢理解, 比如(MethodInvoker)delegate是什么?^_^, 后面的文章会更复杂, 请做好心里准备.

[截图]

相关推荐
csbysj202029 分钟前
如何使用 XML Schema
开发语言
R6bandito_35 分钟前
STM32中printf的重定向详解
开发语言·经验分享·stm32·单片机·嵌入式硬件·mcu
earthzhang202142 分钟前
【1007】计算(a+b)×c的值
c语言·开发语言·数据结构·算法·青少年编程
杨枝甘露小码1 小时前
Python学习之基础篇
开发语言·python
武文斌771 小时前
项目学习总结:LVGL图形参数动态变化、开发板的GDB调试、sqlite3移植、MQTT协议、心跳包
linux·开发语言·网络·arm开发·数据库·嵌入式硬件·学习
爱吃喵的鲤鱼1 小时前
仿mudou——Connection模块(连接管理)
linux·运维·服务器·开发语言·网络·c++
beyond谚语1 小时前
C#学习小笔记(完整版)—— Patience
c#
爱吃小胖橘2 小时前
Unity网络开发--超文本传输协议Http(1)
开发语言·网络·网络协议·http·c#·游戏引擎
郝学胜-神的一滴2 小时前
使用Linux的read和write系统函数操作文件
linux·服务器·开发语言·数据库·c++·程序人生·软件工程
小火柴1232 小时前
利用R语言绘制直方图
开发语言·r语言