[原创][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是什么?^_^, 后面的文章会更复杂, 请做好心里准备.

[截图]

相关推荐
同学小张1 小时前
【端侧AI 与 C++】1. llama.cpp源码编译与本地运行
开发语言·c++·aigc·llama·agi·ai-native
踢球的打工仔2 小时前
PHP面向对象(7)
android·开发语言·php
汤姆yu4 小时前
基于python的外卖配送及数据分析系统
开发语言·python·外卖分析
Yue丶越4 小时前
【C语言】字符函数和字符串函数
c语言·开发语言·算法
翔云 OCR API5 小时前
人脸识别API开发者对接代码示例
开发语言·人工智能·python·计算机视觉·ocr
V***u4535 小时前
MS SQL Server partition by 函数实战二 编排考场人员
java·服务器·开发语言
这是程序猿5 小时前
基于java的ssm框架旅游在线平台
java·开发语言·spring boot·spring·旅游·旅游在线平台
芳草萋萋鹦鹉洲哦5 小时前
【elemen/js】阻塞UI线程导致的开关卡顿如何优化
开发语言·javascript·ui
爱学习的小邓同学5 小时前
C++ --- 多态
开发语言·c++
颜*鸣&空6 小时前
QT实现串口通信+VSPD+串口调试工具
开发语言·qt