了解多线程
操作系统使用进程将它们正在执行的不同应用程序分开。线程是操作系统分配处理器时间的基本单元,一个进程中可以有多个线程同时运行。
如果程序需要与用户操作、分布式操作、进行大量IO或网络操作,这是使用多线程是明智的选择。
要提高对用户的响应速度并且处理所需数据以便几乎同时完成工作,使用多个线程是一种最为强大的技术。
在具有一个处理器的计算机上,多个线程可以通过利用用户事件之间很小的时间段在后台处理数据来达到这种效果。
多个线程主要用于完成以下任务:
通过网络与Web 服务器和数据库进行通信。
执行占用大量时间的操作。
区分具有不同优先级的任务。例如,高优先级线程管理时间关键的任务,低优先级线程执行其他任务。
使用户界面可以在将时间分配给后台任务时仍能快速做出响应。
多个线程的缺点
建议您使用尽可能少的线程,这样可以最大限度地减少操作系统资源的使用,并可提高性能。线程处理还具有在设计应用程序时要考虑的资源要求和潜在冲突。
这些资源要求如下所述:
系统将为进程、AppDomain 对象和线程所需的上下文信息使用内存。
因此,可以创建的进程、AppDomain 对象和线程的数目会受到可用内存的限制。
跟踪大量的线程将占用大量的处理器时间。如果线程过多,管理和调度线程就站越多的资源,程序的性能就越低。
使用许多线程控制代码执行非常复杂,并可能产生许多 bug。
托管线程中的异常
销毁线程需要了解可能发生的问题并对那些问题进行处理。
由于调用了 Abort,线程中将引发 ThreadAbortException。
由于线程执行时所在的应用程序域正在卸载,因此在线程中引发了 AppDomainUnloadedException。
公共语言运行库或宿主进程通过引发内部异常来终止线程。
线程的优先级
每个线程都具有分配给它的线程优先级,可以使用 Thread.Priority 属性获取或设置任何线程的优先级。操作系统还可以动态调整线程优先级,并根据优先级来决定线程的执行顺序。
线程状态
在创建托管线程时,线程处于 Unstarted 状态。当调用 线程的Start方法后,操作系统便启动线程。
线程一旦处于已启动状态,就可以执行许多操作来更改线程状态。下表列出使状态发生更改的操作以及相应的新状态。
另一个线程调用 System.Thread.Start。 Unchanged
线程响应 System.Threading.Thread.Start 并开始运行。 Running
线程调用 System.Threading.Thread.Sleep。WaitSleepJoin
线程对另一个对象调用 System.Threading.Monitor.Wait。 WaitSleepJoin
线程对另一个线程调用 System.Threading.Thread.Join。 WaitSleepJoin
另一个线程调用 System.Threading.Thread.Suspend。 SuspendRequested
线程响应 System.Threading.Thread.Suspend 请求。 Suspended
另一个线程调用 System.Threading.Thread.Resume。 Running
另一个线程调用 System.Threading.Thread.Suspend。 Running
另一个线程调用 System.Threading.Abort。 AbortRequested
线程响应 System.Threading.Abort。 Aborted
线程的处理
NET中线程是通过System.Threading命名空间中的Thread类来处理的。一个Thread类实例表示一个线程。
1、创建并启动线程。Thread newthread=new Thread( new ThreadStart(Method)). Thread构造函数需要一个参数,用于指定线程的入口。因为我们传送的是方法的详细信息,所以需要使用ThreadStart来创建委托。
线程的入口参数不能带任何参数而且不能有返回值。
2、暂停和继续线程。
Thread.Sleep(ms) 阻止线程ms豪秒。
Thread.Suspend() 来暂停线程。
Thread.Resume(),来继续执行线程。
3、终止与销毁线程。
Thread.Abort() 用于永久地停止托管线程.
Thread.Interrupt()可以中断正在等待的线程.
Thread.Join(),它在线程实际停止执行之前,或可选超时间隔结束之前不会返回.
同步数据
在多线程的会发送多个线程同时读写统一资源的情况,为了避免冲突,必须对共享资源进行同步或控制对共享资源的访问。
如果不能很好的解决这种资源的争用与共享,则会导致括死锁和争用条件等问题。
系统提供了可用于协调多个线程之间的资源共享的同步对象。减少线程的数目使同步资源更为容易。
需要同步的资源包括:
系统资源(如通信端口)。
多个进程所共享的资源(如文件句柄)
由多个线程访问的单个应用程序域的资源(如全局、静态和实例字段)。
NET提供了几种可用来同步对实例和静态成员的访问的策略:
同步代码区域。可以使用 Monitor 类或该类的编译器支持来仅同步需要该类的代码块,从而改善性能.
手动同步。可以使用 .NET Framework 类库提供的同步对象。
同步上下文。可以使用 SynchronizationAttribute 为 ContextBoundObject 对象启用简单的自动同步。
Synchronized 属性。Hashtable 和 Queue 等几个类提供了一个可为该类的实例返回线程安全包装的 Synchronized 属性。
线程池
NET提供一个 ThreadPool类来创建辅助线程池,从而是我们可以集中精力于应用程序任务而不是线程管理。.NET使用线程池线程实现多种用途,包括异步 I/O 完成、Timer 回调、注册的等待操作、使用委托的异步方法调用以及 System.Net 套接字连接。
线程池线程是后台线程。 每个线程都使用默认堆栈大小,以默认的优先级运行,并处于多线程单元中。 适合于处理可以后台运行的短期任务。
每个进程只有一个线程池对象。
在以下几种情况下,适合于创建并管理自己的线程而不是使用线程池线程:
需要前台线程。
需要使线程具有特定的优先级。
您的任务会导致线程长时间被阻止。由于线程池具有最大线程数限制,因此大量阻塞的线程池线程可能会阻止任务启动。
需要将线程放入单线程单元。所有 ThreadPool 线程均处于多线程单元中。
您需要具有与线程关联的稳定标识,或使某一线程专用于某一任务。
多线程开发实例


































































































































