c#多线程教学(4):线程池和异步编程

Unity多线程编程实战:Task与Job System性能优化指南 多线程编程是现代软件开发中提升应用性能的核心技术之一,其原理在于将计算任务分配到多个处理器核心并行执行,从而充分利用硬件资源。在游戏开发领域,这项技术对于保障实时渲染的流畅性、处理复杂运算尤为关键。Unity引擎作为主流的游戏开发平台,其特有的线程模型要求开发者必须遵循“主线程操作Unity对象”的铁律,这为多线程应用带来了独特的挑战与解决方案。通过C#的Task异步编程模型与Unity官方的Job System,开发者可以将耗时的CPU密集型任务(如地形生成、图像处理、AI行为树计算)安全地剥离主线程,有 阅读详情

  如果你仔细阅读了我前面的三篇文章,我相信你对用.NET Framework提供的System.Threading.Thread类和一些线程同步的类基本的线程知识和多线程编程知识很了解。我们将在这里进一步讨论一些.NET类,以及他们在多线程编程中扮演的角色和怎么编程。它们是:

  System.Threading.ThreadPool 类

  System.Threading.Timer 类

  如果线程的数目并不是很多,而且你想控制每个线程的细节诸如线程的优先级等,使用Thread是比较合适的;但是如果有大量的线程,考虑使用线程池应该更好一些,它提供了高效的线程管理机制来处理多任务。 对于定期的执行任务Timer类是合适的;使用代表是异步方法调用的首选。

System.Threading.ThreadPool Class

  当你创建应用程序时,你应该认识到大部分时间你的线程在空闲的等待某些事件的发生(诸如按下一个键或侦听套节子的请求)。毫无疑问的,你也会认为这是绝对的浪费资源。

  如果这里有很多的任务需要完成,每个任务需要一个线程,你应该考虑使用线程池来更有效的管理你的资源并且从中受益。线程池是执行的多个线程集合,它允许你添加以线程自动创建和开始的任务到队列里面去。使用线程池使得你的系统可以优化线程在CPU使用时的时间碎片。但是要记住在任何特定的时间点,每一个进程和每个线程池只有一个一个正在运行的线程。这个类使得你的线程组成的池可以被系统管理,而使你的主要精力集中在工作流的逻辑而不是线程的管理。

  当第一次实例化ThreadPool类时线程池将被创建。它有一个默认的上限,即每处理器最多可以有25个,但是这个上限是可以改变的。这样使得处理器不会闲置下来。如果其中一个线程等待某个事件的发生,线程池将初始化另外一个线程并投入处理器工作,线程池就是这样不停的创建工作的线程和分配任务给那些没有工作的在队列里的线程。唯一的限制是工作线程的数目不能超过最大允许的数目。每个线程将运行在默认的优先级和使用默认的属于多线程空间的堆栈大小空间。一旦一项工作任务被加入队列,你是不能取消的。

  请求线程池处理一个任务或者工作项可以调用QueueUserWorkItem方法。这个方法带一个WaitCallback代表类型的参数,这个参数包装了你药完成的任务。运行时自动为每一个的任务创建线程并且在任务释放时释放线程。

  下面的代码说明了如何创建线程池和怎样添加任务:

public void afunction(object o) 

{ 

// do what ever the function is supposed to do. 

} 

//thread entry code 

{ 

// create an instance of WaitCallback 

WaitCallback myCallback = new WaitCallback (afunction); 

//add this to the thread pool / queue a task 

ThreadPool.QueueUserWorkItem (myCallback); 

}


  你也可以通过调用ThreadPool.RegisterWaitForSingleObject方法来传递一个System.Threading.WaitHandle,当被通知或者时间超过了调用被System.Threading.WaitOrTimerCallback包装的方法。

  线程池和基于事件的编程模式使得线程池对注册的WaitHandles的监控和对合适的WaitOrTimerCallback代表方法的调用十分简单(当WaitHandle被释放时)。这些做法其实很简单。这里有一个线程不断的观测在线程池队列等待操作的状态。一旦等待操作完成,一个线程将被执行与其对应的任务。因此,这个方法随着出发触发事件的发生而增加一个线程。

  让我们看看怎么随事件添加一个线程到线程池,其实很简单。我们只需要创建一个ManualResetEvent类的事件和一个WaitOrTimerCallback的代表,然后我们需要一个携带代表状态的对象,同时我们也要决定休息间隔和执行方式。我们将上面的都添加到线程池,并且激发一个事件:

public void afunction(object o) 

{ 

// do what ever the function is supposed to do. 

} 


//object that will carry the status information

public class anObject 

{ 

} 

//thread entry code 

{ 

//create an event object

ManualResetEvent aevent = new ManualResetEvent (false); 


// create an instance of WaitOrTimerCallback 

WaitOrTimerCallback thread_method = new WaitOrTimerCallback (afunction); 


// create an instance of anObject 

anObject myobj = new anObject(); 


// decide how thread will perform 

int timeout_interval = 100; // timeout in milli-seconds. 

bool onetime_exec = true; 


//add all this to the thread pool. 

ThreadPool. RegisterWaitForSingleObject (aevent, thread_method, myobj, timeout_interval, onetime_exec); 


// raise the event 

aevent.Set(); 

}


  在QueueUserWorkItem和RegisterWaitForSingleObject方法中,线程池创建了一个后台的线程来回调。当线程池开始执行一个任务,两个方法都将调用者的堆栈合并到线程池的线程堆栈中。如果需要安全检查将耗费更多的时间和增加系统的负担,因此可以通过使用它们对应的不安全的方法来避免安全检查。就是ThreadPool.UnsafeRegisterWaitForSingleObject 和ThreadPool.UnsafeQueueUserWorkItem。

  你也可以对与等待操作无关的任务排队。 Timer-queue timers and registered wait operations也使用线程池。它们的返回方法也被放入线程池排队。

  线程池是非常有用的,被广泛的用于。NET平台上的套节子编程,等待操作注册,进程计时器和异步的I/O。对于小而短的任务,线程池提供的机制也是十分便利处于多线程的。线程池对于完成许多独立的任务而且不需要逐个的设置线程属性是十分便利的。但是,你也应该很清楚,有很多的情况是可以用其他的方法来替代线程池的。比如说你的计划任务或给每个线程特定的属性,或者你需要将线程放入单个线程的空间(而线程池是将所有的线程放入一个多线程空间),抑或是一个特定的任务是很冗长的,这些情况你最好考虑清楚,安全的办法比用线程池应该是你的选择。


System.Threading.Timer Class

  Timer类对于周期性的在分离的线程执行任务是非常有效的,它不能被继承。

  这个类尤其用来开发控制台应用程序,因为System.Windows.Forms.Time是不可用的。比如同来备份文件和检查数据库的一致性。
  当创建Timer对象时,你药估计在第一个代理调用之前等待的时间和后来的每次成功调用之间的时间。一个定时调用发生在方法的应得时间过去,并且在后来周期性的调用这个方法。你可以适应Timer的Change方法来改变这些设置的值或者使Timer失效。当定时器Timer不再使用时,你应该调用Dispose方法来释放其资源。

  TimerCallback代表负责指定与Timer对象相关联的方法(就是要周期执行的任务)和状态。它在方法应得的时间过去之后调用一次并且周期性的调用这个方法直到调用了Dispose方法释放了Timer的所有资源。系统自动分配分离的线程。

  让我们来看一段代码看看事如何创建Timer对象和使用它的。我们首先要创建一个TimerCallback代理,在后面的方法中要使用到的。如果需要,下一步我们要创建一个状态对象,它拥有与被代理调用的方法相关联的特定信息。为了使这些简单一些,我们传递一个空参数。我们将实例化一个Timer对象,然后再使用Change方法改变Timer的设置,最后调用Dispose方法释放资源。

// class that will be called by the Timer 

public class WorkonTimerReq 

{ 

public void aTimerCallMethod() 

{ 

// does some work

} 

} 


//timer creation block 

{ 

//instantiating the class that gets called by the Timer. 

WorkonTimerReq anObj = new WorkonTimerReq () ; 


// callback delegate 

TimerCallback tcallback = new TimerCallback(anObj. aTimerCallMethod) ; 


// define the dueTime and period 

long dTime = 20 ; // wait before the first tick (in ms) 

long pTime = 150 ; // timer during subsequent invocations (in ms) 


// instantiate the Timer object 

Timer atimer = new Timer(tcallback, null, dTime, pTime) ; 


// do some thing with the timer object 

... 

//change the dueTime and period of the Timer 

dTime=100; 

pTime=300; 

atimer.Change(dTime, pTime) ; 

// do some thing 

... 

atimer.Dispose() ; 

... 

}



异步编程

  这部分内容如果要讲清楚本来就是很大的一部分,在这里,我不打算详细讨论这个东西,我们只是需要直到它是什么,因为多线程编程如果忽律异步的多线程编程显然是不应该的。异步的多线程编程是你的程序可能会用到的另外一种多线程编程方法。

  在前面的文章我们花了很大的篇幅来介绍线程的同步和怎么实现线程的同步,但是它有一个固有的致命的缺点,你或许注意到了这一点。那就是每个线程必须作同步调用,也就是等到其他的功能完成,否则就阻塞。当然,某些情况下,对于那些逻辑上相互依赖的任务来说是足够的。异步编程允许更加复杂的灵活性。一个线程可以作异步调用,不需要等待其他的东西。你可以使用这些线程作任何的任务,线程负责获取结果推进运行。这给予了那些需要管理数目巨大的请求而且负担不起请求等待代价的企业级的系统更好的可伸缩性。

  .NET平台提供了一致的异步编程机制用于ASP.NET,I/O,Web Services,Networking,Message等。


后记

  由于学习的时候很难找到中文这方面的资料,因此我就只好学习英文的资料,由于水平不高,翻译的时候可能难免曲解原文的意思,希望大家能够指出,同时希望这些东西能够给大家在学习这方面知识给予一定的参考和帮助,那怕是一点点,就很欣慰了。

Geoserver新手必看:5分钟搞定世界地图发布(附中国省市数据) 本文为Geoserver新手提供了快速发布世界地图的实战指南。从环境搭建、数据准备入手,详细讲解了如何创建工作区、添加数据存储、发布图层及配置关键参数,并最终通过创建图层组实现地图服务的整合与预览。文章旨在帮助用户快速掌握Geoserver发布地图服务的核心流程与实用技巧。 阅读详情

相关推荐

基于Mind+、MOTT实现人工智能

@基于Mind+、MOTT实现人工智能 人工智能实验 一、实验目的及要求 【一】实现人脸识别 【二】实现云数据库应用 【三】实现测温数据mqtt上传至物联网云平台 二、实验原理与内容 基于二哈实现多人人脸学习和识别 基于TinywebDB实现云数据库应用 基于EasyIoT实现mqtt数据上传。 三、实验软硬件环境 硬件:掌控板 软件:Mind+ 四、实验过程(实验步骤、记录、数据、分析) 1.基于二哈实现多人人脸学习和识别 ①在Mind+扩展上的传感器选项选择HUSKYLENS AI 摄像头 ②配置哈士

weixin_44606930的博客 2371

C#.NET多线程教学(4):线程池和异步编程

  前3章内容回顾:c#.net多线程编程教学(1):多任务和多线程c#.net多线程编程教学(2):Thread类 c#.net多线程编程教学(3):线程同步    如果你仔细阅读了我前面的三篇文章,我相信你对用.NET Framework提供的System.Threading.Thread类和一些线程同步的类基本的线程知识和多线程编程知识很了解。我们将在这里进一步讨论一

ASP.NET学习资料搜集BLOG 1216

ISP模块之色彩增强算法--HSV空间Saturation通道调整

色彩增强不同于彩色图像增强,图像增强的一般处理方式为直方图均衡化等,目的是为了增强图像局部以及整体对比度。而色彩增强的目的是为了使的原有的不饱和的色彩信息变得饱和、丰富起来。对应于Photoshop里面的“色相/饱和度”调节选项里面对饱和度的操作。色彩增强的过程,并不改变原有彩色图像的颜色以及亮度信息。     在我的色彩增强算法模块里面,始终只针对色彩饱和度(Saturation)信息做研究,

松间明月 1万+

c#.net多线程教学(4):线程池和异步编程

如果你仔细阅读了我前面的三篇文章,我相信你对用.NET Framework提供的System.Threading.Thread类和一些线程同步的类基本的线程知识和多线程编程知识很了解。我们将在这里进一步讨论一些.NET类,以及他们在多线程编程中扮演的角色和怎么编程。它们是:  System.Threading.ThreadPool 类  System.Threading.Timer 类  如果线程

Ar7的专栏 1726

手把手教你配置C6678的SPI启动:从NorFlash烧写到多核加载的完整流程

本文详细介绍了TMS320C6678多核DSP的SPI启动全流程,包括硬件准备、镜像文件生成与转换、NorFlash烧写与验证、多核启动同步机制以及常见问题排查。通过实战演示,帮助开发者高效配置SPI启动模式,解决启动失败、多核同步异常等问题,提升嵌入式系统开发效率。

weixin_27076351的博客 151

【晶振专题】晶振学习笔记——ST AN2867应用手册 2

通过学习AN2867设计指南,我们知道皮尔斯晶振的基本知识。也了解了晶振的负载电容计算方法、安全因子测试方法和反馈电阻的作用。

一点硬件 1364

C#多线程学习(四) 多线程的自动管理(线程池)

在多线程的程序中,经常会出现两种情况: 一种情况:应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应 这一般使用ThreadPool(线程池)来解决; 另一种情况:线程平时都处于休眠状态,只是周期性地被唤醒 这一般使用Timer(定时器)来解决; ThreadPool类提供一个由系...

weixin_30477797的博客 162

【RH850/U2A】:HSM与APP通信(中断方式)

HSM与APP通信(中断方式)

1992

C#多线程

1、基本概念 进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Win

裕之天下的专栏 764

【数据集8】全球人口数据WorldPop详解

全球人口数据WorldPop详解

WW、forever的博客 7878

YOLOv8 交通流量监测详解

本文介绍了一个基于YOLOv8的交通流量监测系统,该系统通过深度学习技术实现车辆实时检测、跟踪和分类。系统核心功能包括:1)使用YOLOv8模型检测道路车辆并进行持续跟踪;2)按方向和车型统计车流量;3)支持多区域流量监测和数据可视化。文章提供了完整的代码实现示例,涵盖基础车辆检测、视频流处理和高级数据分析功能。系统还可进一步优化性能,如使用轻量级模型、GPU加速等,并建议扩展车速估算、密度分析等功能。该方案为交通管理提供了有效的实时监测和决策支持工具。

u010117029的博客 346

C#线程操作常见的六大操作方法

来自:http://developer.51cto.com/art/200908/147771.htm C#线程操作常见的操作方法是什么呢?C#线程操作方法的具体实现是什么样子的呢?那么下面我们来看看具体的C#线程操作的六大方法分别是什么,以及他们的特点是什么? C#线程操作一、用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程 在C#

拓 1514

温升试验详解

温升试验是电子设备可靠性验证的重要手段,用于评估器件在正常工作或极限条件下的热稳定性。试验通过测量器件表面或关键点温度与环境温度的差值(ΔT),判断是否存在过热风险。主要依据行业标准,采用热电偶、热像仪等设备测量稳态温度。热阻分析可建立温升与功耗的关系,指导器件选型、PCB热设计和散热结构优化。典型应用包括电源模块和LED电路测试。温升试验通过系统性热分析,能有效提升产品在高负载、高温环境下的可靠性和安全性,对现代小型化、高密度电子设备尤为重要。

硬核科技 1329

c#.net多线程编程教学(4):线程池和异步编程

前3章内容回顾:c#.net多线程编程教学(3):线程同步  c#.net多线程编程教学(2):Thread类 c#.net多线程编程教学(1):多任务和多线程如果你仔细阅读了我前面的三篇文章,我相信你对用.NET Framework提供的System.Threading.Thread类和一些线程同步的类基本的线程知识和多线程编程知识很了解。我们将在这里进一步讨论一些.NET类,以及他们在多线程编

wxd0963的专栏 1099

假人有限元模型

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

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

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

C# 多线程的学习大纲

C# 多线程编程是开发高效并发应用的核心技术之一。以下是一个详细的学习大纲,涵盖了 C# 多线程编程的各个方面,从基础概念到高级主题。

weixin_39604653的博客 1086

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C#多线程编程 | 深入解析多线程在实际项目中的应用与优化

首先,培训班的课程内容非常重要。一个好的编程培训班应该提供系统的学习计划,包括基础编程语言的教学、算法与数据结构的讲解、项目实战的训练等。在使用`Task`进行并行计算时,C#提供了强大的异常捕获机制,可以通过`Task.WhenAny()`、`Task.WhenAll()`等方法进行任务的控制和管理,从而确保系统稳定性。最后,C#中的异步编程(`async`/`await`)为开发者提供了一种更加高效、易于理解的并发模型,适合处理大量的I/O操作,而不会阻塞线程,进一步提升了应用程序的响应性。

ekdjyw_767的博客 435

C#多线程并行编程

C# 多线程 线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。 线程是轻量级进程。一个使用线程的常见实例是现代操作系统中并行编程的实现。使用线程节省了 CPU 周期的浪费,同时提高了应用程序的效率。 到目前为止我们编写的程序是一个单线程作为应用程序的运行实例的单一的过程运行的。...

di_pingxian的博客 855

零基础学C#异步编程:Task入门指南

Task是C#中表示异步操作的核心类,它就像一张"任务票据"——你发起一个任务后,可以继续做其他事情,等需要结果时再凭票据领取。与传统的多线程不同,Task更智能地利用线程池,避免了频繁创建销毁线程的开销。刚开始接触C#异步编程时,Task这个概念让我既好奇又困惑。异步编程是现代C#开发的必备技能,希望这篇指南能帮你建立清晰的学习路径。记住从简单案例开始,逐步构建复杂应用,遇到问题多查文档,很快你就能写出高效的异步代码了!记住:async/await是语法糖,本质还是Task在运作。

SunstoneLion34的博客 365

.Net开发中的多线程编程-文章

微软.Net开发中的多线程编程文章,在www.webjx.com上搜索到的。http://www.webjx.com/search.php?type=title&keywords=%B6%E0%CF%DF%B3%CCVB.Net-C#多线程Thread-代理委托delegate编程 1、微软.Net开发中的多线程编程总结2007-10-152、Visual C#多线程参

VB.Net+Android.java 1619

新书上架!!《C#高级编程:从新手到高手(300集视频)》

想入门怕看不懂?学完基础遇瓶颈?这本书让你一次搞定!面向多层次读者独立性与连贯性并存实战案例教学紧贴实际需求。

weixin_41851599的博客 267
上一篇: c#.net多线程编程教学(3):线程同步
下一篇: c#多线程教学(5):Case 学习多线程
MagicxiaoZ
博客等级 码龄19年 5粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值