[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#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点: 在线程池中调用委托 在线程池中执行异步操作 线程池和并行度 实现取消选项 使用等待句柄和超时 使用计时 ...
随机推荐
- CDOJ 486 Good Morning 傻逼题
Good Morning Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/486 ...
- TreeView节点拖拉操作1
TreeView节点拖拉操作1 //事先设置 TreeView1.DragMode= dmAutomatic; unit Unit1; interface uses Windows, Me ...
- Android手机拨打电话的开发实例
一部手机最常用的功能就是打电话和发短信了,在Android开发中我们如何通过程序拨打电话呢?本文就给出一个用Android手机拨打电话的简单的实例. 下面是开发此实例的具体步骤: 一.新建一个Andr ...
- Dia Diagram Mac OSX Yosemite Fix 闪退 xterm
[转]http://navkirats.blogspot.hk/2014/10/dia-diagram-mac-osx-yosemite-fix-i-use.html I use the Dia to ...
- MySQL内存----使用说明全局缓存+线程缓存) 转
MySQL内存使用说明(全局缓存+线程缓存) 首先我们来看一个公式,MySQL中内存分为全局内存和线程内存两大部分(其实并不全部,只是影响比较大的 部分): per_thread_buffers=(r ...
- Logistic回归总结
原文:http://blog.csdn.net/dongtingzhizi/article/details/15962797 Logistic回归总结 作者:洞庭之子 微博:洞庭之子-Bing (2 ...
- 终于找到了无毒版的fences1.0(2.0版本要收费的)
今天终于安装了fences1.0,桌面不用那么乱哄哄的啦 我在博客里上传了安装文件,方便大家下载安装,这是无毒的哦,网上有很多都是不能通过病毒检测的. 地址如下:点击这里下载 使用方法: 创建块:安装 ...
- Android(java)学习笔记82:我们到底该如何处理异常?
我们到底该如何处理异常? 原则: 如果该功能内部可以将问题处理,用try,自己能解决就自己解决问题. 如果处理不了,交由调用者处理,这是用throws,自己不能解决的问题,我们就抛出去交个调用者解决这 ...
- uva 10152 ShellSort 龟壳排序(希尔排序?)
今天状态总是很糟,这种题目卡了一天... 是不是休息时间太少了,头脑迟钝了... 名字叫希尔排序,我还以为跟它有关,还搜索了下资料. 只要找到trick就会发现是很水的题目.只要对比下就能找到哪些是移 ...
- python(3)-函数动态参数
先来看一段代码 def show(*arg): print(arg, type(arg)) if __name__ == "__main__": show(1) show(1,2, ...