托管线程处理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
托管线程处理
托管线程处理基本知托管线程处理基本知识识
线程与线程处线程与线程处理理
操作系统使用进程将它们正在执行的不同应用程序分开。线程是操作系统分配处理器时间的基本单元,并且进程中可以有多个线程同时执行代码。每个线程都维护异常处理程序、调度优先级和一组系统用于在调度该线程前保存线程上下文的结构。线程上下文包括为使线程在线程的宿主进程地址空间中无缝地继续执行所需的所有信息,包括线程的 CPU 寄存器组和堆栈。
.NET Framework 将操作系统进程进一步细分为由 System.AppDomain
表示的、称为应用程序域的轻量托管子进程。一个或多个托管线程(由 System.Threading.Thread 表示)可以在同一个托管进程中的一个或任意数目的应用程序域中运行。虽然每个应用程序域都是用单个线程启动的,但该应用程序域中的代码可以创建附加应用程序域和附加线程。其结果是托管线程可以在同一个非托管进程中的应用程序域之间自由移动;您可能只有一个线程在若干应用程序域之间移动。
支持抢先多任务处理的操作系统可以创建多个进程中的多个线程同时执行的效果。它通过以下方式实现这一点:在需要处理器时间的线程之间分割可用处理器时间,并轮流为每个线程分配处理器时间片。当前执行的线程在其时间片结束时被挂起,而另一个线程继续运行。当系统从一个线程切换到另一个线程时,它将保存被抢先的线程的线程上下文,并重新加载线程队列中下一个线程的已保存线程上下文。
时间片的长度取决于操作系统和处理器。由于每个时间片都很小,因此即使只有一个处理器,多个线程看起来似乎也是在同时执行。这实际上就是多处理器系统中发生的情形,在此类系统中,可执行线程分布在多个可用处理器中。
多个线程的优多个线程的优点点
无论如何,要提高对用户的响应速度并且处理所需数据以便几乎同时完成工作,使用多个线程是一种最为强大的技术。在具有一个处理器的计算机上,多个线程可以通过利用用户事件之间很小的时间段在后台处理数据来达到这种效果。例如,在另一个线程正在重新计算同一应用程序中的电子表格的其他部分时,用户可以编辑该电子表格。 无需修改,同一个应用程序在具有多个处理器的计算机上运行时将极大地满足用户的需要。单个应用程序域可以使用多个线程来完成以下任务:
•
通过网络与 Web 服务器和数据库进行通信。 •
执行占用大量时间的操作。 •
区分具有不同优先级的任务。例如,高优先级线程管理时间关键的任务,低优先级线程执行其他任务。 • 使用户界面可以在将时间分配给后台任务时仍能快速做出响应。
多个线程的缺多个线程的缺点点
建议您使用尽可能少的线程,这样可以最大限度地减少操作系统资源的使用,并可提高性能。线程处理还具有在设计应用程序时要考虑的资源要求和潜在冲突。这些资源要求如下所述:
•
系统将为进程、AppDomain 对象和线程所需的上下文信息使用内存。因此,可以创建的进程、AppDomain 对象和线程的数目会受到可用内存的限制。 •
跟踪大量的线程将占用大量的处理器时间。如果线程过多,则其中大多数线程都不会产生明显的进度。如果大多数当前线程处于一个进程中,则其他进程中的线程的调度频率就会很低。 •
使用许多线程控制代码执行非常复杂,并可能产生许多 bug 。 • 销毁线程需要了解可能发生的问题并对那些问题进行处理。
提供对资源的共享访问会造成冲突。为了避免冲突,必须对共享资源进行同步或控制对共享资源的访问。如果在相同或不同的应用程序域中未能正确地使访问同步,则会导致出现一些问题,这些问题包括死锁和争用条件等,其中死锁是指两个线程都停止响应,并且都在等待对方完成;争用条件是指由于意外地出现对两个事件的执行时间的临界依赖性而发生反常的结果。系统提供了可用于协调多个线程之间的资源共享的同步对象。减少线程的数目使同步资源更为容易。
需要同步的资源包括:
•
系统资源(如通信端口)。 •
多个进程所共享的资源(如文件句柄)。 • 由多个线程访问的单个应用程序域的资源(如全局、静态和实例字段)。
线程处理与应用程序设线程处理与应用程序设计计
一般情况下,要为不会阻止其他线程的相对较短的任务处理多个线程并且不需要对这些任务执行任何特定调度时,使用 ThreadPool 类是一种最简单的方式。但是,有多个理由创建您自己的线程:
•
如果您需要使一个任务具有特定的优先级。 •
如果您具有可能会长时间运行(并因此阻止其他任务)的任务。 •
如果您需要将线程放置到单线程单元中(所有 ThreadPool 线程均处于多线程单元中)。 •
如果您需要与该线程关联的稳定标识。例如,您应使用一个专用线程来中止该线程,将其挂起或按名称发现它。 • 如果您需要运行与用户界面交互的后台线程,.NET Framework 2.0 版提供了 BackgroundWorker
组件,该组件可以使用事件与用户界面线程的跨线程封送进行通信。
为多线程处理同步数为多线程处理同步数据据
当多个线程可以调用单个对象的属性和方法时,对这些调用进行同步处理是非常重要的。否则,一个线程可能会中断另一个线程正在执行的任务,使该对象处于一种无效状态。其成员不受这类中断影响的类叫做线程安全类。 “公共语言基础结构”提供了几种可用来同步对实例和静态成员的访问的策略:
•
同步代码区域。可以使用 Monitor 类或此类的编译器支持来仅同步需要此类的代码块,从而提高性能。 •
手动同步。可以使用 .NET Framework 类库提供的同步对象。请参见 同步基元概述,这部分对 Monitor 类进行了讨论。 •
同步上下文。可以使用 SynchronizationAttribute 为 ContextBoundObject 对象启用简单的自动同步。 • Synchronized 属性。Hashtable 和 Queue 等几个类提供了一个可为该类的实例返回线程安全包装的
Synchronized 属性。请参见集合和同步(线程安全)。
前台和后台线前台和后台线程程
托管线程或者是后台线程,或者是前台线程。后台线程不会使托管执行环境处于运行状态,除此之外,后台线程与前台线程是一样的。一旦所有前台线程在托管进程(其中 .exe
文件是托管程序集)中被停止,系统将停止所有后台线程并关闭。 注意注意:: 当运行库因为进程关闭而停止某个后台线程时,不会在该线程中引发异常。但是,当线程是因为 AppDomain.Unload 方法卸载应用程序域而停止时,将同时在后台和前台线程中引发 ThreadAbortException 。
可使用 Thread.IsBackground 属性确定线程是后台线程还是前台线程,或更改其状态。通过将其 IsBackground 属性设置为 true ,可在任何时候将线程更改为后台线程。
重要说明重要说明::
线程的前台或后台状态不影响线程中未处理异常的结果。在 .NET Framework 2.0
版中,前台或后台线程中的未处理异常都将导致应用程序终止。请参见 托管线程中的异常。