线程处理用于使程序能够执行并发处理,同时执行多个操作。C#中有三种线程的使用方法,BackgroundWorker组件、线程池、自己创建使用线程,接下来分别介绍如何使用。
1.使用BackgroundWorker组件(创建多线程处理程序最可靠方法)
此类管理一个专用于处理指定方法的单独线程。
在此事件处理程序中调用耗时的操作。
调用 RunWorkerAsync 函数,开始后台操作。
处理 ProgressChanged 事件,收到进度更新的通知。
处理RunWorkerCompleted 事件,在操作完成时收到通知。
但是,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(1000); Console.WriteLine("main thread signaling worker thread..."); autoEvent.Set();
Console.ReadLine(); } }
执行结果
Mutex 对象,与监视器类似。
使用这个类的方法可以安全地递增、递减、交换和比较任何线程中的值。
ReaderWriterLock 类在线程修改资源时将强制其独占访问资源,但在读取资源时则允许非独占访问。ReaderWriterLock 类定义支持单个写线程和多个读线程的锁。
死锁,多线程应用程序始终存在deadlock 的危险,在编码前多考虑,避免死锁。
4.线程计时器。System.Threading.Timer 类可用于定期在单独的线程上运行任务,创建实例后计时器开始启动。
参考https://msdn.microsoft.com/zh-cn/library/ms173178.aspx