[C#]线程处理
线程处理用于使程序能够执行并发处理,同时执行多个操作。C#中有三种线程的使用方法,BackgroundWorker组件、线程池、自己创建使用线程,接下来分别介绍如何使用。
1.使用BackgroundWorker组件(创建多线程处理程序最可靠方法)
此类管理一个专用于处理指定方法的单独线程。
添加 DoWork 事件的事件处理程序,为后台操作做好准备,在此事件处理程序中调用耗时的操作。
调用 RunWorkerAsync 函数,开始后台操作。
处理 ProgressChanged 事件,收到进度更新的通知。
处理RunWorkerCompleted 事件,在操作完成时收到通知。
处理 ProgressChanged 和 RunWorkerCompleted 事件的方法可以访问应用程序的用户界面,原因是这两个事件是在调用了 RunWorkerAsync 方法的线程上引发的。 但是,DoWork 事件处理程序无法使用任何用户界面对象,因为它在后台线程上运行。
2.线程池,是可以用来在后台执行多个任务的线程集合,将任务添加到队列,然后在创建线程后自动启动这些任务。线程池通常用于服务器应用程序。 每个传入请求都将分配给线程池中的一个线程,因此可以异步处理请求,而不会占用主线程,也不会延迟后续请求的处理。一旦池中的某个线程完成任务,它将返回到等待线程队列中,等待被再次使用,这种重用使应用程序可以避免为每个任务创建新线程的开销。线程池通常具有最大线程数限制。如果所有线程都繁忙,则额外的任务将放入队列中,直到有线程可用时才能够得到处理。
ThreadPool.QueueUserWorkItem(WaitCallback callBack)//将方法排入队列以便执行。 ThreadPool.QueueUserWorkItem(WaitCallback callBack, object state)//将方法排入队列以便执行,并指定包含该方法所用数据的对象。
3.创建和使用线程
如果需要对应用程序的线程的行为进行更多的控制,则可以自己管理线程。通过声明类型为 Thread 的变量,并调用为要对新线程执行的过程或方法提供名称的构造函数,从而创建一个新线程。
System.Threading.Thread newThread = new System.Threading.Thread(AMethod);
线程其他知识点:
1.前台/后台线程
后台线程与前台线程完全一样,只是后台线程不会阻止进程终止。前台线程的运行时间不限定,而后台线程则在最后一个前台线程停止时立即停止。 可以使用 IsBackground 属性确定或更改线程的后台状态。默认情况下,主线程、通过Thread类构造函数创建的线程在前台执行,线程池线程、从非托管代码进入托管环境的线程在后台执行。
2.线程的参数和返回值
为线程提供参数:将目标方法包裹在类中,并为该类定义字段,这些字段将被用作新线程的参数。
从线程获取返回值:使用BackgroundWorker 组件来管理线程,在任务完成时引发RunWorkerCompleted 事件,然后用事件处理程序处理结果。
3.线程同步
在应用程序中使用多个线程,必须协调对资源(如文件句柄、网络连接和内存)的访问。C#中的线程同步方法有锁、监视器、同步事件和等待句柄、Mutex对象、Interlocked类、ReaderWriter锁。
锁:lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。
监视器:与lock关键字类似,防止多个线程同时执行代码块,但是lock更简洁、更安全。
同步事件和等待句柄:同步事件有终止、非终止两个状态的对象,用来激活和挂起线程,让线程等待一个非终止同步事件可以将线程挂起,将事件状态变为终止可以激活线程。如果线程尝试等待已经终止的事件,则线程继续执行,不会受到延迟。同步事件有AutoResetEvent和ManualResetEvent两种,只要AutoResetEvent 激活线程,其状态自动从终止变为非终止,ManualResetEvent 允许它的终止状态激活任意个线程,并只有调用其Reset方法时才还原到非终止状态。
通过调用WaitOne、WaitAny、WaitAll等待方法使线程等待事件,当调用事件的Set方法,事件变为终止状态。
using System;
using System.Threading; class ThreadingExample
{
static AutoResetEvent autoEvent; static void DoWork()
{
Console.WriteLine(" worker thread started, now waiting on event...");
autoEvent.WaitOne();
Console.WriteLine(" worker thread reactivated, now exiting...");
} static void Main()
{
autoEvent = new AutoResetEvent(false); Console.WriteLine("main thread starting worker thread...");
Thread t = new Thread(DoWork);
t.Start(); Console.WriteLine("main thread sleeping for 1 second...");
Thread.Sleep(); Console.WriteLine("main thread signaling worker thread...");
autoEvent.Set(); Console.ReadLine();
}
}
执行结果

Mutex 对象,与监视器类似。
Interlock类,使用 Interlocked 类的方法来避免在多个线程尝试同时更新或比较同一个值时可能出现的问题。使用这个类的方法可以安全地递增、递减、交换和比较任何线程中的值。
ReadWriter锁,只在写入数据时锁定资源,在不更新数据时允许多个客户端同时读取数据。 ReaderWriterLock 类在线程修改资源时将强制其独占访问资源,但在读取资源时则允许非独占访问。ReaderWriterLock 类定义支持单个写线程和多个读线程的锁。
死锁,多线程应用程序始终存在deadlock 的危险,在编码前多考虑,避免死锁。
4.线程计时器。System.Threading.Timer 类可用于定期在单独的线程上运行任务,创建实例后计时器开始启动。
参考https://msdn.microsoft.com/zh-cn/library/ms173178.aspx
[C#]线程处理的更多相关文章
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- [高并发]Java高并发编程系列开山篇--线程实现
Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- Java 线程
线程:线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须拥有一个父进程.线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源.它与父进程的其他线程共享该进程的所有资 ...
- C++实现线程安全的单例模式
在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...
- 记一次tomcat线程创建异常调优:unable to create new native thread
测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...
- Android线程管理之ThreadLocal理解及应用场景
前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...
- C#多线程之线程池篇3
在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...
- C#多线程之线程池篇2
在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...
- C#多线程之线程池篇1
在C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点: 在线程池中调用委托 在线程池中执行异步操作 线程池和并行度 实现取消选项 使用等待句柄和超时 使用计时 ...
随机推荐
- [Codeforces] 347B - Fixed Points
题意:给定一个序列,现有一种操作:两个数的位置互换.问最多操作一次.序列 [元素位置i] 与 [元素Ai] 相等的最多个数? 依据题意,最多个数为 : [操作之前[元素位置i] 与 [元素Ai] ...
- SuperToolTips
https://github.com/nhaarman/supertooltips supertooltips-master.zip
- 如何将松散的dll打包进需要发布的exe
我们需要发布的exe文件很多时候都可能会依赖于一堆松散的dll,如果想在发布的时候只提供exe文件,而不想把一大堆dll一起放在和exe同一个文件夹下,是有方法的,该方法由CLR via C#作者提出 ...
- cocos2d-x如何优化内存的应用
自身以前也写过cocos2d-x如何优化内存的应用,以及内存不够的情况下怎么样处置惩罚游戏.今天在微博中看到有友好简介了下内存,挺详细的.不晓得是谁写的,我纪录下. 一,IOS与图片内存 在IOS上, ...
- iOS开发——图形编程OC篇&OpenGL ES2.0编程步骤
OpenGL ES2.0编程步骤 OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机.PDA和游戏主机等嵌入式设备而设 ...
- 分享php中四种webservice实现的简单架构方法及实例(转)
本人所了解的webservice有以下几种:PHP本身的SOAP,开源的NUSOAP,商业版的PHPRPC,以及使用二进制传输数据流的 HessianPHP,那么一下就简单的介绍下这几种webserv ...
- codeigniter分页类传多个参数(转)
http://example.com/index.php/控制器/方法名/页面的偏移值 页面的偏移值必须是方法名后第一个参数,否者分页类不能判断当前是哪一页,而用ci的分页类进行页面跳转时他是把偏移值 ...
- Linux编程之《进程/线程绑定CPU》
Intro----- 通常我们在编写服务器代码时,可以通过将当前进程绑定到固定的CPU核心或者线程绑定到固定的CPU核心来提高系统调度程序的效率来提高程序执行的效率,下面将完整代码贴上. /***** ...
- MySQL在Django框架下的基本操作(MySQL在Linux下配置)
[原]本文根据实际操作主要介绍了Django框架下MySQL的一些常用操作,核心内容如下: ------------------------------------------------------ ...
- 小白日记16:kali渗透测试之弱点扫描-openvas、nessus
漏洞扫描工具 1.openvas OpenVAS是开放式漏洞评估系统,也可以说它是一个包含着相关工具的网络扫描器.在kali上默认集成openvas.在kali上,配置相对简单[几乎每天都在更新] 实 ...