c#多线程教学(5):Case 学习多线程

C# 委托中的多线程 什么是多线程?我们在建立以个C#项目时,往往会在Form1上添加控件,然后写代码,初学者都是在重复这个过程,其实这个过程是单线程的,可以理解为只有“main”主线程,有的时候往往需要同时测量多个东西,比如说在扫面局域网主机时,如果按一个一个主机的IP去扫描,会很浪费时间,因为当一个主机未开机,会对这个主机等待一直到超时。如果建立多个线程,让所有的IP 扫描分配给不同的线程去执行,因此会节省很多时间,尤其是扫面的IP段主机大部分没开机,和单线程比花费的时间差很多。 阅读详情

  在前面的多线程编程系列的文章中,我们了解了在.NET中多线程编程必须要掌握的基本知识,但是可能大家看了文章之后,感觉还是很模糊,对一个具体的编程可能还是觉得无从下手,究其原因可能是理论讲的过多,而没有太多的实际参考例子,造成收获不大。因此,在接下来的文章中,我将给出几个典型的多线程编程的实例,让大家有更清楚的认识。

Case 1 - No synchronization

  在我们的第一个例子中,有两类线程,两个是读线程,一个是写线程,两个线程是并行运行的并且需要访问同一个共享资源。读线程在写线程之前启动,用于设置共享变量的值。我使用Thread.Sleep来完成这些工作。摘录代码如下:

Thread t0 = new Thread(new ThreadStart(WriteThread));

Thread t1 
= new Thread(new ThreadStart(ReadThread10));

Thread t2 
= new Thread(new ThreadStart(ReadThread20));

t0.IsBackground
=true;

t1.IsBackground
=true;

t2.IsBackground
=true;

t0.Start();

t1.Start();

t2.Start();



  正如所看到的那样,读线程启动之后立即启动两个写线程。下面的代码是两个读线程和写线程所执行的代码。

 

public void WriteThread()
{
Thread.Sleep(
1000);
m_x
=3;
}
 
public void ReadThread10()
{
int a = 10;
for(int y=0;y<5;y++)
{
string s = "ReadThread10";
s 
= s + " # multiplier= ";
s 
= s + Convert.ToString(a) + " # ";
s 
= s + a * m_x;
listBox1.Items.Add(s);
Thread.Sleep(
1000);
}

}

public void ReadThread20()
{
int a = 20;
for(int y=0;y<5;y++)
{
string s = "ReadThread20";
s 
= s + " # multiplier= ";
s 
= s + Convert.ToString(a) + " # ";
s 
= s + a * m_x;
listBox1.Items.Add(s);
Thread.Sleep(
1000);
}

}


  最后运行的结果如下:

  通过上面的运行结果,我们可以明显的看出运行结果并不是我们所期望的那样,开始的两个结果,读线程运行在写线程之前,这是我们极力要避免发生的事情。


Case 2 - Synchronization [One WriteThread - Many ReadThreads]
  下面我将使用ManualResetEvent来解决上面遇到的问题来达到线成的同步,唯一不同的是我们在启动读线程和写线程之前使用安全的方法。

Thread t0 = new Thread(new ThreadStart(SafeWriteThread));

Thread t1 
= new Thread(new ThreadStart(SafeReadThread10));

Thread t2 
= new Thread(new ThreadStart(SafeReadThread20));

t0.IsBackground
=true;

t1.IsBackground
=true;

t2.IsBackground
=true;

t0.Start();

t1.Start();

t2.Start();



  添加一个ManualResetEvent:


  看看SafeWriteThread的代码:

public void SafeWriteThread()
{
m_mre.Reset();
WriteThread();
m_mre.Set();
}




  Reset设置ManualResetEvent的状态为non-signaled,这意味着事件没有发生。接着我们来调用WriteThread方法,实际上可以跳过Reset这一步,因为我们在ManualResetEvent的构造函数设置其状态为non-signaled。一旦WriteThread线程返回,调用Set方法设置ManualResetEvent的状态为signaled。

  下面让我们来看看另外两个SafeReadThread方法:

public void SafeReadThread10()
{
m_mre.WaitOne();
ReadThread10();
}

public void SafeReadThread20()
{
m_mre.WaitOne();
ReadThread20();
}




  WaitOne方法将阻塞当前的线程直到ManualResetEvent的状态被设置为signaled。在这里,我们程序中的两个读线程都将阻塞至SafeWriteThread完成任务后调用Set方法。这样我们就确保了两个读线程在写线程完成对共享资源的访问之后才执行。


Case 3 - Synchronization [Many WriteThreads - Many ReadThreads]

  下面我们将模拟更为复杂的情形。在下面的程序中,有多个写线程和读线程。读线程只有在所有的写线程完成了任务之后才能访问共享资源。在实际的情况中,读线程可能是并行的运行,但是为了简便起见,我使写线程运行有一定的顺序,只有在前一个写线程完成之后,第二个写线程才能启动。
  在这里,我增加了一个ManualResetEvent对象和ManualResetEvent的数组。

public ManualResetEvent m_mreB;

public ManualResetEvent[] m_mre_array;


  添加初始化代码:

m_mreB = new ManualResetEvent(false);

m_mre_array 
= new ManualResetEvent[2];

m_mre_array[
0]=m_mre;

m_mre_array[
1]=m_mreB;


  启动四个线程:

Thread t0 = new Thread(new ThreadStart(SafeWriteThread));

Thread t0B 
= new Thread(new ThreadStart(SafeWriteThreadB));

Thread t1 
= new Thread(new ThreadStart(SafeReadThread10B));

Thread t2 
= new Thread(new ThreadStart(SafeReadThread20B));

t0.IsBackground
=true;

t0B.IsBackground
=true;

t1.IsBackground
=true;

t2.IsBackground
=true;

t0.Start();

t0B.Start();

t1.Start();

t2.Start();


  在这里有两个StartThreads和两个WriteThreads,让我们看看他们的执行:

public void SafeWriteThread()

{
m_mre.Reset();

WriteThread();

m_mre.Set();
}


public void SafeWriteThreadB()

{ 
m_mreB.Reset();

m_mre.WaitOne();

Thread.Sleep(
1000);

m_x
+=3; 

m_mreB.Set();
}



  我对第二个WriteThread使用了另外一个事件对象,为了模拟等待第一个线程完成工作。

public void SafeReadThread10B()

{
WaitHandle.WaitAll(m_mre_array);

ReadThread10();
}


public void SafeReadThread20B()

{
WaitHandle.WaitAll(m_mre_array);

ReadThread20();
}




  在这里,使用了一个WaitAll的方法,他是WaitHandle基类提供给ManualResetEvent的静态方法,它的参数为我们在前面定义的ManualResetEvent数组。他阻塞当前的线程直到参数数组里面所有的ManualResetEvent对象设置状态为signaled,换一句话说就是等待他们完成了各自的任务。 

 

m_mre = new ManualResetEvent(false);

 

C#网络编程实战:从TCP聊天室到UDP广播的5个经典案例(附完整源码) 本文通过5个从简到繁的实战案例,系统讲解C#网络编程核心技能。内容涵盖TCP回声服务器、多线程聊天室、可靠文件传输、UDP广播服务发现及高性能异步服务器,每个案例均提供完整源码,帮助开发者快速掌握网络应用编程,有效应对期末项目或实际开发需求。 阅读详情

相关推荐

2024最新指南:如何用Python批量下载Sentinel-2数据(附避坑清单)

本文提供2024年最新Python批量下载Sentinel-2遥感数据的完整指南,涵盖环境配置、API准备、核心下载流程实现及实战避坑清单。通过智能查询器、断点续传下载器等实用工具,帮助用户高效获取遥感数据,避免常见网络问题和数据完整性验证失败。

silver的专栏 619

C# 多线程编程——理解多线程(一)

一、线程的基础知识 1.1 System.Threading.Thread类 System.Threading.Thread是用于控制线程的基础类,通过Thread可以控制当前应用程序域中线程的创建、挂起、停止、销毁。公共属性如下: 属性名称 说明 CurrentContext 获取线程正在其中执行的当前上下文。 CurrentThread 获取当前...

kingshown_WZ的专栏 1万+

RAG——RAG 索引(文档解析技术)

本文介绍了RAG系统中文档解析的关键技术,重点分析了如何通过LangChain的Document Loaders处理多种格式文档。文章指出高质量文档解析对RAG系统效果的决定性作用,并详细讲解了PDF、TXT、Word等常见格式的解析方法。作者提供了代码示例和Gitee开源项目链接,特别强调了PDF解析的深入方案,同时介绍了相关依赖库的安装配置。文章还展示了如何定义通用文档加载方法,为开发者提供了实用的技术参考。

小志的博客 753

稍加改进的Switch/Case扩展方法

引言 鹤冲天的《c#扩展方法奇思妙用》系列给了我很多启示,其中的很多用法大大提升了代码编写效率,最近小研究了一下他提供的《c#扩展方法奇思妙用变态篇三:switch/case组扩展》一文提供的扩展方法,并依照自己的习惯重新实现了一下,现分享一下我的实现。   范例 先看一下他原文中的范例: 我觉得这里唯一不爽的就是高亮的那部分,因为这里必需要显式声明类型并作后续处理,我希望直接让...

weixin_34342905的博客 225

【知识分享】什么是同轴传输线结构?

同轴传输线的几何形状由中心导体组,嵌在介电材料(Dielectric)中,并且,被连续的外导体所包围,也被称为屏蔽(Shield)。内外导体有相同的几何中心轴,因此得名同轴(Coaxial)。

一只豌豆象的博客 2372

TC3XX - MCAL知识点(一):新建Tc3xx EB-tresos工程

基于EB-tresos建立Hightec或者Tasking工程的时候,第一个步骤就是需要新建一个EB-tresos的工程,本文记录一下如何新建一个EB-tresos工程,以及对其进行简单的操作。那么Tc3xx的MCAL包含哪些内容呢?

梦想技术家 2973

C#委托主线程调用控件并且同步UI界面显示以及协议制作

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.

技术工厂 1639

无人机正射影像DOM孔洞修补的另一种方法并调整影像色差(附GlobalMapper24安装包(中文注册版))

之前介绍了用GlobalMapper联合PhotoShop对无人机正射影像DOM进行破洞修补,但是ps修图非常耗时,需要耐心和足够的细心。对于大面积的水域空洞,纹理特征都差不多,没必要修补得那么细致入微,本文介绍另一种直接在Global Mapper中快速修补大面积水域空洞的方法。 一、Global Mapper中检查数据 二、使用“数字化”工具,绘制需要补洞的多边形区域 三、导出绘制好的矢量区域 四、打开影像下载软件,选择影像图源 五、下载影像 六、调整影像的色差 七、合并影像并输出 八、检查结果数据

从地图看世界的专栏 1549

C#高级--多线程详解

C#高级–多线程详解 零、文章目录 一、什么是多线程 1、进程 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。 2、线程 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。 3、句柄 句柄是Windows系统中对象或实例的标识,这些对象包括模块、应用程序实例、窗口、控制、位图、GDI对象、资源、文件等。 4、多线程 (1)多线程概念 多线程是指程序中

李宥的博客 5万+

使用MATLAB和Simulink来设计并仿真一个智能家居火灾报警系统

智能家居火灾报警系统旨在通过烟雾传感器、温度传感器等设备监测家庭环境,一旦检测到异常情况(如烟雾或温度骤升),立即触发警报并采取相应措施。在这个教程中,我们将使用MATLAB和Simulink来设计并仿真一个智能家居火灾报警系统,包括数据采集、处理以及响应机制。

amy_mhd的博客 162

【Matlab】matlab代码实现迭代学习控制

该文介绍了在Matlab中实现迭代学习控制(ILC)的方法。ILC通过利用历史轨迹数据来优化重复任务的控制性能。文章提供了一个步进电机控制示例,包括:1)定义正弦轨迹;2)设置100次迭代和0.1学习率;3)建立二阶系统模型;4)执行ILC算法计算控制输入;5)绘制期望轨迹与实际输出的对比图。该示例展示了ILC的基本实现过程,并指出实际应用可能需要更复杂的设计。代码演示了误差计算、控制输入更新和结果可视化等关键步骤。

unber的博客 201

C# 泛型、文件、委托事件与多线程

表格分类编码范围占用空间用途控制字符0 ~ 31、1271 字节系统控制、格式指令(换行、回车)可打印字符32 ~ 1261 字节数字、字母、标点、空格总结一句话: ASCII 是字符与数字的映射规则,C# 通过强制类型转换实现双向互转;利用固定编码区间,可以快速判断字符类型、完成大小写转换,是字符串底层操作的核心基础。

m0_74303839的博客 372

倍福--RS232自由口实现

RS232/485通信协议是在现场中常用到的,比如触摸屏、温控模块等设备控控制器做通信,会常用到此类协议,本文介绍RS232/485自由口通信的实现,并用PC调试助手进行测试。 目 录 软硬件版本 3 1.1. 倍福Beckhoff 3 1.1.1. 控制器硬件 3 1.1.2. 控制器软件 3 硬件连接 3 2.1. PC COM介绍 3 2.2. RS232/RS485连接 3 3.2.1. N030…………. 4 3.2.2. N031…………. 4 2.3. 实际线路连接 5 PLC程序 7 3

weixin_41883890的博客 3284

C#学习记录——入门到进阶

输入输出 //输出语句:换行输出 Console.WriteLine("hool,word"); Console.WriteLine("hool c#"); //输出语句,无换行输出 Console.Write("hool word"); Console.Write("hool c#"); //

i_like_python3的博客 2947

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

2025年这些实用的C#/.NET知识点你都知道吗?

在这个快速发展的技术世界中,时常会有一些重要的知识点、信息或细节被忽略或遗漏。《C#/.NET/.NET Core拾遗补漏》专栏我们将探讨一些可能被忽略或遗漏的重要知识点、信息或细节,以帮助大家更全面地了解这些技术栈的特性和发展方向。✍C#/.NET/.NET Core拾遗补漏合集🚀C#/.NET/.NET Core拾遗补漏Issues投稿😎DotNetGuide技术社区微信交流8群欢迎加入DotNetGuide技术社区微信交流8群!

专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享。这里聚焦了大量的C#/.NET/.NET Core优质文章、开源项目、实用工具和学习、工作、面试心得。 1399

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C#/.NET/.NET Core拾遗补漏合集(24年6月更新)

在这个快速发展的技术世界中,时常会有一些重要的知识点、信息或细节被忽略或遗漏。《C#/.NET/.NET Core拾遗补漏》专栏我们将探讨一些可能被忽略或遗漏的重要知识点、信息或细节,以帮助大家更全面地了解这些技术栈的特性和发展方向。欢迎加入DotNetGuide技术社区交流群C#/.NET/.NET Core全面的学习、工作、面试指南知识库。

专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享。这里聚焦了大量的C#/.NET/.NET Core优质文章、开源项目、实用工具和学习、工作、面试心得。 1347

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

《C语言、C++、C# 从基础到进阶:三大编程语言系统学习指南》

本指南系统讲解 C语言、C++ 与 C# 的核心基础、语法特性、应用领域、学习路线和面试重点。内容涵盖变量、数据类型、流程控制、数组、函数、指针、结构体、面向对象、STL、集合、LINQ、异步编程、.NET 开发等知识,适合零基础入门、编程基础巩固、后端与系统开发方向学习者参考。

zzwokstyle的博客 484

C# 学习笔记

文章目录C# 编程规范代码书写规则命名规则关键字排序直接插入法类定义、继承、覆盖、属性定义 C# 编程规范 代码书写规则 1、尽量使用接口,然后使用类实现接口,以提高程序的灵活性。 2、尽量不要手工更改计算机生成的代码,若必须更改,一定要改成和计算机生成的代码风格一样。 3、关键的语句(包括声明关键的变量)必须要写注释。 4、建议局部变量在最接近使用它的地方声明。 5、不要使用goto系列语句,除非是用在跳出深层循环时。 6、避免写超过5个参数的方法。如果要传递多个参数,则使用结构。 7、避免书写代码量过大

程序猿-Jojo 523

你可能遗漏的一些C#/.NET/.NET Core知识点

在这个快速发展的技术世界中,时常会有一些重要的知识点、信息或细节被忽略或遗漏。《C#/.NET/.NET Core拾遗补漏》专栏我们将探讨一些可能被忽略或遗漏的重要知识点、信息或细节,以帮助大家更全面地了解这些技术栈的特性和发展方向。

专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享。这里聚焦了大量的C#/.NET/.NET Core优质文章、开源项目、实用工具和学习、工作、面试心得。 2798

C#/.NET/.NET Core拾遗补漏合集(24年11月更新)

在这个快速发展的技术世界中,时常会有一些重要的知识点、信息或细节被忽略或遗漏。《C#/.NET/.NET Core拾遗补漏》专栏我们将探讨一些可能被忽略或遗漏的重要知识点、信息或细节,以帮助大家更全面地了解这些技术栈的特性和发展方向。一个包含了 50+ C#/.NET编程技巧实战练习教程欢迎加入DotNetGuide技术社区微信交流7群,即将满员!

专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享。这里聚焦了大量的C#/.NET/.NET Core优质文章、开源项目、实用工具和学习、工作、面试心得。 1212

c#.net 多线程编程学习(3)

Case 学习多线程在前面的多线程编程系列的文章中,我们了解了在.NET中多线程编程必须要掌握的基本知识,但是可能大家看了文章之后,感觉还是很模糊,对一个具体的编程可能还是觉得无从下手,究其原因可能是理论讲的过多,而没有太多的实际参考例子,造成收获不大。因此,在接下来的文章中,我将给出几个典型的多线程编程的实例,让大家有更清楚的认识。Case 1 - No synchronization  在

884

C#/.NET/.NET Core拾遗补漏合集(25年6月更新)

在这个快速发展的技术世界中,时常会有一些重要的知识点、信息或细节被忽略或遗漏。《C#/.NET/.NET Core拾遗补漏》专栏我们将探讨一些可能被忽略或遗漏的重要知识点、信息或细节,以帮助大家更全面地了解这些技术栈的特性和发展方向。✍C#/.NET/.NET Core拾遗补漏Issues投稿🚀C#/.NET/.NET Core拾遗补漏Gitee合集📚C#/.NET/.NET Core拾遗补漏GitHub合集。

专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享。这里聚焦了大量的C#/.NET/.NET Core优质文章、开源项目、实用工具和学习、工作、面试心得。 1198

一个包含 80+ C#/.NET 编程技巧实战练习开源项目

C#/.NET/.NET Core编程常用语法、算法、技巧、中间件、类库、工作业务实操练习集,配套详细的文章教程讲解,助你快速掌握C#/.NET/.NET Core中各种编程常用语法、算法、技巧、中间件、类库、工作业务实操等等。C#/.NET/.NET Core全面的学习、工作、面试指南知识库!

专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享。这里聚焦了大量的C#/.NET/.NET Core优质文章、开源项目、实用工具和学习、工作、面试心得。 1249

C#/.NET/.NET Core拾遗补漏合集(25年4月更新)

在这个快速发展的技术世界中,时常会有一些重要的知识点、信息或细节被忽略或遗漏。《C#/.NET/.NET Core拾遗补漏》专栏我们将探讨一些可能被忽略或遗漏的重要知识点、信息或细节,以帮助大家更全面地了解这些技术栈的特性和发展方向。

专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享。这里聚焦了大量的C#/.NET/.NET Core优质文章、开源项目、实用工具和学习、工作、面试心得。 1729
上一篇: c#多线程教学(4):线程池和异步编程
下一篇: Visual C++中函数调用方式浅探
MagicxiaoZ
博客等级 码龄19年 5粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值