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);

 

【AFAC2026金融智能-赛题四】我做了一个疯狂的决定,把Embedding和Reranker全删了 本文介绍了AFAC2026金融智能挑战赛赛道四的解题思路,核心是在500万token的严格限制下实现金融长文本的高效问答。作者通过四步流水线(规划、BM25检索、记忆压缩、LLM推理)优化流程,重点创新在于: 采用零API调用的纯BM25检索,配合多路查询、封面页加权和页面邻接扩展等策略 设计高效的检索算法,从问题中提取专有名词并构建多路查询组合 深入理解评分公式,平衡准确率和token消耗,最终在准确率提升的同时将token消耗从数百万降至百万级 这些创新使方案在严格限制下实现了性能突破,展示了在资源受限 阅读详情

相关推荐

解决Visual C++2008安装失败,error 1935

重装系统后Visual C++没了,其他都能装上但VC2008会报这个error 1935。鉴于我把网上所有的解决方法排了一遍错,我也不知道是哪一步起效,所以就都放上来了。特别注意:报error 1935的错误原因可能不尽相同,比如我的报错开头为An error occurred,结尾为HRESULT:0x80070005。80070005 拒绝访问通常是权限问题,安装Visual C++无法写入文件夹或注册表(直接跳转第7步)

weixin_44427808的博客 1万+

C#网络编程实战:从TCP聊天室到UDP广播的5个经典案例(附完整源码)

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

weixin_29212429的博客 576

英飞凌TC3xx的GTM模块到底有多强?从PWM生成到电机驱动,一篇讲透车载定时器核心

本文深入解析英飞凌TC3xx系列中的GTM模块在汽车电子领域的强大功能,从PWM生成到电机驱动的全链路设计。通过模块化架构和硬件级解决方案,GTM显著提升系统精度和响应速度,适用于电机控制、电源管理等复杂场景。文章结合实战经验,详细拆解GTM的技术实现和性能优势。

weixin_27741699的博客 202

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

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

kingshown_WZ的专栏 1万+

揭秘个人开发者接支付宝的‘野路子’:不用企业资质,用Python模拟扫码转账与回调监听

本文探讨了个人开发者如何通过Python模拟支付宝扫码转账与回调监听的技术实现,解析了支付宝URL协议格式,并设计了本地化的支付状态监听方案。文章强调该方法仅用于技术研究,实际应用需遵守支付宝官方接口和金融合规要求。

weixin_30736301的博客 408

低功耗基础概念——Level Shifter cell补充

信号跨越不同级别电压模块进行驱动时,需要使用level shifter。 H2L Level shifer 从高电压到低电压的level shifter,可以是两个反相器的串联。 输入高电平区域信号INH,输出低电平区域信号OUTL,注意供应电源由低电压模块提供,即图中的VDDL。 从图中可以看出,H2L的level shifter只会引入一个buffer的延迟,对时序的影响较小。 L2H Level shifer 用低电压区域的信号invert和buffer之后得到的一对信号来驱动工作在高电压区域的交

qq_36480087的博客 1万+

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

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

weixin_34342905的博客 225

如何对TBSS的结果进行统计学的分析,已完成置换检验,如何在最终的TBSS输出结果提取除具体值及如何做进一步相关性分析??

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值。

**My Coding Family** 1438

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

电磁场仿真:电磁场基础理论_(13).微波技术基础

微波是指频率在300 MHz到300 GHz之间的电磁波。这一频率范围对应的波长为1米到1毫米。

2401_87715305的博客 1316

图神经网络实战(2)——图论基础

图论 (Graph theory) 是数学的一个基本分支,涉及对图研究。图是复杂数据结构的可视化表示,有助于理解不同实体之间的关系。图论提供了大量建模和分析现实问题的工具,如交通系统、社交网络和互联网等。在本节中,将介绍图论的基本原理,主要涉及三个方面:图属性、图概念和图算法。

盼小辉丶的博客 1万+

C#高级--多线程详解

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

李宥的博客 5万+

YOLO26改进策略【多YAML融合】| UNetV2 + BiFormer + WIoU

Wise-IoU是一种基于IoU的损失函数,旨在解决目标检测中边界框回归损失函数在处理低质量训练数据时的问题。

Limiiiing的博客 218

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

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

m0_74303839的博客 371

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

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

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

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

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

i_like_python3的博客 2946

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

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

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

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

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

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

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

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

zzwokstyle的博客 482

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优质文章、开源项目、实用工具和学习、工作、面试心得。 1211

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优质文章、开源项目、实用工具和学习、工作、面试心得。 1195

一个包含 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、付费专栏及课程。

余额充值