C#_多线程编程入门

字面理解:多个线程同时工作的过程。

案例①   单线程

        #region ① 单线程做菜/// <summary>/// ① 单线程做菜:执行任务时,什么操作都动不了./// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void SingleThread_Click(object sender, EventArgs e){Thread.Sleep(3000);MessageBox.Show("素菜做好了","友情提示");Thread.Sleep(3000);MessageBox.Show("荤菜做好了", "友情提示");}#endregion

单线程_效果

做菜(先做完素菜,再做荤菜)时,当前窗口无法操作(移动、拉伸等)。

案例②  多线程

        #region ② 多线程做菜/// <summary>/// ② 多线程做菜:执行任务时,可以对其他功能操作/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void multiThreading_Click(object sender, EventArgs e){Thread thread = new Thread(() =>{Thread.Sleep(3000);MessageBox.Show("素菜做好了", "友情提示");Thread.Sleep(5000);MessageBox.Show("荤菜做好了", "友情提示");});thread.Start();}#endregion

多线程_效果

做菜(先做完素菜,再做荤菜)时,当前窗口进可以行操作(移动、拉伸等)。

案例③  任务

        #region ③ 任务做菜/// <summary>/// ③ 任务做菜:执行任务时,可以对其他功能操作/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnTask_Click(object sender, EventArgs e){Task.Run(() =>{Thread.Sleep(3000);MessageBox.Show("素菜做好了", "友情提示");Thread.Sleep(5000);MessageBox.Show("荤菜做好了", "友情提示");});}#endregion

任务_效果

做菜(先做完素菜,再做荤菜)时,当前窗口进可以行操作(移动、拉伸等)。

案例④  同步

        #region ④ 同步做菜/// <summary>/// ④ 同步做菜:同时运行任务/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSynchornization_Click(object sender, EventArgs e){Task.Run(() =>{Thread.Sleep(3000);MessageBox.Show("素菜做好了", "友情提示");});Task.Run(() =>{Thread.Sleep(5000);MessageBox.Show("荤菜做好了", "友情提示");});}#endregion

同步_效果

素菜和荤菜可以同时做,当前窗口进可以行操作(移动、拉伸等)。

案例⑤  异步

        #region 做好菜了,来吃饭(异步)/// <summary>/// ⑤ 做好菜了,来吃饭(异步):等待任务完成后,才继续往下执行./// </summary>/// <param name="sender"></param>/// <param name="e"></param>private async void btnAsync_Click(object sender, EventArgs e){await Task.Run(() =>{Thread.Sleep(3000);MessageBox.Show("素菜做好了", "友情提示");Thread.Sleep(5000);MessageBox.Show("荤菜做好了", "友情提示");});MessageBox.Show("做好菜了,来吃饭", "友情提示");}#endregion

异步_效果

等待完成这个任务完成后,才执行“来吃饭”;UI和逻辑不在同个线程。

案例⑥  并行

        #region ⑥ 做好菜了,来吃饭(并行)/// <summary>/// ⑥ 做好菜了,来吃饭(并行):异步完成任务后,才继续往下执行./// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnParallel_Click(object sender, EventArgs e){//1. 创建泛型为Task的集合对象List<Task> Ltasks = new List<Task>();//2. 添加任务Ltasks.Add(Task.Run(() =>{Thread.Sleep(3000);MessageBox.Show("素菜做好了", "友情提示");}));Ltasks.Add(Task.Run(() =>{Thread.Sleep(5000);MessageBox.Show("荤菜做好了", "友情提示");}));//3. 将所有Task对象完成后,创建新的异步延续任务Task.WhenAll(Ltasks).ContinueWith(ts =>{MessageBox.Show("做好菜了,来吃饭", "友情提示");});}#endregion

并行_效果

等待完成所有任务完成后,才执行“来吃饭”;UI和逻辑不在同个线程。

案例⑦  使用线程组件跨线程传输信息和状态

namespace MyWorkBook.MyTest
{public partial class ThreadForm : Form{public ThreadForm(){InitializeComponent();backgroundWorker1.WorkerReportsProgress = true;//是否支持发送进度报告。backgroundWorker1.WorkerSupportsCancellation = true;//是否支持取消异步操作。}/// <summary>/// 线程控件触发事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e){//通过Object对象可以获取线程组件;以下代码会另起一个线程,而不是在UI线程中运行。BackgroundWorker worker = sender as BackgroundWorker;for(int i = 1; i <= 100; i++){if(worker.CancellationPending == true)//应用程序已请求取消后台操作{e.Cancel = true;//取消事件--更改运行返回状态,并不能取消停止break;}else{Thread.Sleep(50);//实际应用编码时,该程式是为工作代码。worker.ReportProgress(i);//当线程进度发给改变时,触发线程组件发生改变后触发事件(backgroundWorker1_ProgressChanged)并传参。
/*发送*/var data = Tuple.Create("Hallen",true,27);//创建元数组数据。worker.ReportProgress(i, data);}}e.Result = e.Argument;//根据操作异步参数给操作异步结果赋值---应用于线程完成(失败/成功)后触发事件。}/// <summary>/// 线程组件发生改变后触发事件---在创建BackgroundWorker线程上执行,是异步调用,和引发事件代码是在不同线程。/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e){progressBar1.Value = e.ProgressPercentage;//将异步任务进度百分比赋值给进度条resultLabel.Text = (e.ProgressPercentage.ToString() + "%");//将异步任务进度百分比赋值给标签组件显示进度数值/*接收---跨线程接收信息和状态*/if(e.UserState != null){Tuple<string, bool, int> data = (Tuple<string, bool, int>)e.UserState;lbl_state.Text = $"姓名{data.Item1},性别{data.Item2},年龄{data.Item3}";}            }/// <summary>/// 启动按钮触发事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e){if(backgroundWorker1.IsBusy != true)//判断异步操作不在进行{backgroundWorker1.RunWorkerAsync("你是坏淫吗?对,你是的。");//开始异步操作}}/// <summary>/// 取消按钮触发事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button2_Click(object sender, EventArgs e){if(backgroundWorker1.WorkerSupportsCancellation == true)//判断支持异步取消操作{backgroundWorker1.CancelAsync();//请求取消挂起后台操作}}/// <summary>/// 线程完成(失败/成功)后触发事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){if(e.Cancelled == true)//后台操作已取消{resultLabel.Text = "Canceled";}else if(e.Error != null)//异步操作期间发生错误{resultLabel.Text = "Error:"+ e.Error.Message;}else//后台操作成功{resultLabel.Text = "Done! Result = "+ e.Result;}}}
}

 运行效果

案例⑧  使用Invoke跨线程传输信息和状态

        #region ②串口数据接收事件/// <summary>/// ②串口数据接收事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)//串口数据接收事件{Invoke((EventHandler)delegate  //在UI线程上执行委托,而以下代码是委托需求。{Thread.Sleep(20);if (radioButton4.Checked)//接收模式为字符模式{string str1 = serialPort1.ReadExisting();//字符串模式读textBox1.AppendText(str1 + "\r\n");}//添加内容if (radioButton2.Checked)//接收模式为数值模式{byte data = (byte)serialPort1.ReadByte();//此处需要强制类型转换,将int类型数据转换byte类型数据,不必考虑是否丢失数据string str2 = Convert.ToString(data, 16).ToUpper();//转换为大写十六进制字符串textBox1.AppendText("0x" + (str2.Length == 1 ? "0" + str2 : str2) + "\r\n");}if (radioButton6.Checked)//接收模式为中文模式{//在c#中,如果是通过串口要给下位机发送中文编码或给其他软件(如串口调试助手),则最好采用unicode编码//System.Text.UnicodeEcoding unic= new System.Text.UnicodeEcoding ();//Byte[] writeBytes = unic.GetBytes("你好世界");---接收//serialPort.Write(writeBytes, 0, writeBytes.Length);--发送UTF8Encoding utf8 = new UTF8Encoding();//创建UTF8编码对象Byte[] readBytes = new Byte[serialPort1.BytesToRead];//获取缓冲区数据的字节数serialPort1.Read(readBytes, 0, readBytes.Length);String decodedString = utf8.GetString(readBytes);//UTF8解码后转换为string类型textBox1.AppendText(decodedString + "\r\n");}});}#endregion

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/89999.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux通信--构建进程通信IPC的方案之共享内存|实现使用共享内存进行serverclient通信

共享内存是最快的IPC形式。一旦这样的内存映射到共享它的进程地址空间&#xff0c;这些进程间数据传递不再涉及到内核&#xff0c;即进程不再通过执行进入内核的系统调用来传递彼此的数据。 目录 一、共享内存的原理 二、使用共享内存 三、共享内存函数 1.shmget(用来创建共…

研华I/O板卡 Win10+Qt+Cmake 开发环境搭建

文章目录 一.研华I/O板卡 Win10QtCmake 开发环境搭建 一.研华I/O板卡 Win10QtCmake 开发环境搭建 参考这个链接安装研华I/O板卡驱动程序系统环境变量添加研华板卡dll Qt新建一个c项目 cmakeList.txt中添加研华库文件 cmake_minimum_required(VERSION 3.5)project(advantechDA…

基于爬行动物算法优化的BP神经网络(预测应用) - 附代码

基于爬行动物算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于爬行动物算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.爬行动物优化BP神经网络2.1 BP神经网络参数设置2.2 爬行动物算法应用 4.测试结果&#xff1a;5…

【C++】—— C++11之可变参数模板

前言&#xff1a; 在C语言中&#xff0c;我们谈论了有关可变参数的相关知识。在C11中引入了一个新特性---即可变参数模板。本期&#xff0c;我们将要介绍的就是有关可变参数模板的相关知识&#xff01;&#xff01;&#xff01; 目录 序言 &#xff08;一&#xff09;可变参…

kafka架构和原理详解

Apache Kafka 是一个分布式流数据平台,用于高吞吐量、持久性、可扩展的发布和订阅消息。它具有高度的可靠性,被广泛用于构建实时数据流处理、日志收集和数据管道等应用。 基本架构 1. 主题(Topic): 主题是消息的逻辑分类生产者将消息发布到特定的主题中,而消费者可以订阅…

gitlab提交项目Log in with Access Token错误

目录 报错信息 问题描述 解决方案 报错信息 问题描述 在提交项目到gitlab时&#xff0c;需要添加账户信息 &#xff0c;但是报了这样一个错&#xff0c;原因应该就是路径问题&#xff0c;我在填写server地址的时候&#xff0c;就出现了路径问题&#xff0c;我把多余的几个/…

远传水表数据是怎么远传的?

随着科技的不断发展&#xff0c;智慧城市的建设逐渐成为城市发展的重要方向&#xff0c;而智能水表作为智慧城市中的重要组成部分&#xff0c;它的数据远传功能更是给水务管理带来了极大的便利。下面就由在智能水电表行业摸爬滚打多年的小编来为大家讲解下吧! 一、远传水表数据…

在 Spring Boot 中集成 MinIO 对象存储

MinIO 是一个开源的对象存储服务器&#xff0c;专注于高性能、分布式和兼容S3 API的存储解决方案。本文将介绍如何在 Spring Boot 应用程序中集成 MinIO&#xff0c;以便您可以轻松地将对象存储集成到您的应用中。 安装minio 拉取 minio Docker镜像 docker pull minio/minio创…

正交实验如何进行方差分析?

一、案例介绍 欲研究温度&#xff08;℃&#xff09;、时间&#xff08;min&#xff09;、催化剂含量&#xff08;%&#xff09;对某物质转化率的影响&#xff0c;当前使用正交试验设计进行试验&#xff0c;试探究3个因素对转化率的影响是否显著&#xff0c;并找到能使转化率达…

精读《算法题 - 地下城游戏》

今天我们看一道 leetcode hard 难度题目&#xff1a;地下城游戏。 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士…

设计模式之命令模式(Command)的C++实现

1、命令模式的提出 在软件开发过程中&#xff0c;“行为请求者”和“行为实现者”通常呈现一种“紧耦合”&#xff0c;如果行为的实现经常变化&#xff0c;则不利于代码的维护。命令模式可以将行为的请求者和行为的实现者进行解耦。具体流程是将行为请求者封装成一个对象&…

vulhub之MinIO信息泄露漏洞(CVE-2023-28432)

文章目录 0x01 前言0x02 漏洞描述0x03 影响范围0x04 漏洞复现1.启动环境2.查看端口3.构造POC 0x05 修复建议 0x01 前言 本次测试仅供学习使用&#xff0c;如若非法他用&#xff0c;与本文作者无关&#xff0c;需自行负责&#xff01;&#xff01;&#xff01; 0x02 漏洞描述 …