1 线程的含义
NET 引入了应用程序域(AppDomain)的概念。
-
几个关键点:
◆ Windows 使用的技术叫做“抢先式多任务”。所谓抢先式指的是不允许线程运行比其时限更长的时间。操作系统总是会切入并运行其他线程,这就确保一个线程不会消耗机器的全部处理能力,损害其他线程。
◆ 我们无法确定一个线程何时中断,另一个线程何时运行
。这是多线程比较复杂的主要原因,因为它可能导致两个线程争抢访问同一内存。如果试图用锁定解决这种竞争, 在两个线程试图访问同一锁定区域时,可能会出现死锁的情况。
◆ 在Windows 中, 线程是执行代码的实体。这就意味着操作系统主要关注的是线程的调度
,保证CPU 在所有的时间都处于繁忙状态。操作系统不会调度进程,也不会调度应用程序域。
◆ 线程有优先级, Windows 总是让优先级比较高的线程先执行,优先级比较低的线程后执行。实际上,如果优先级比较高的线程已经准备就绪, Windows 会缩减优先级比较低的线程的时限,让优先级比较高的线程尽快执行。最终的结果是Windows 偏向于优先级比较高的线程
。
◆ 终止一个线程并开始另一个线程的行为称为环境切换(context switching)
。这个切换非常快,但要注意己创建的线程数。每个活动的线程在其时限(至多20μs)的最后都会进行环境切换。如果创建的线程太多,操作系统在不同的线程之间切换所花费的时间就会很长,甚至线程中的代码根本就没有机会运行,因为线程刚刚开始就到了终止的时间。创建成千上万的线程并不是好的解决方案,因此要在应用程序所需要的线程数和Windows能处理的线程数之间找到一个平衡点。至于到底需要创建多少个线程,并没有一个合适的答案,只有了解环境切换和多做测试后才能确知。
-
线程安全性与线程亲和性:
◉ 大多数.NET Framework 基类库都不是"线程安全" 的。线程安全的代码是可以由多个线程同时调用且不产生负面影响的代码。
◉ Windows 窗体控件不是线程安全的,如果同时被多个线程访问, 就无法正常工作。为了确定.NET 基类库中的方法是否是线程安全的,可以参阅在线帮助。如果没有与该方法相关的线程内容,则该方法就不是线程安全的。
◉ .NET Framework 的Windows 窗体子集不仅不是线程安全的, 而且具有“线程亲和性”。线程亲和性是指, 由一个线程创建的对象只能由该线程使用
,其他线程不应与这些对象交互。在Windows 窗体中,必须确保一个Wmdows 窗体对象(例如窗体和控件)不能同多个线程交互。这是非常重要的,因为在创建交互式多线程应用程序时,必须保证只有创建窗体的线程与该窗体交互。
-
后台线程的基本要求:
指示后台任务已经开始
定期提供状态或进度消息
指示后台任务已经完成
允许用户请求取消后台任务
我们希望后台任务能通知用户它何时开始、停止,并提供进度信息。Windows 窗体具有的线程亲和性使这一点更加复杂,因为后台线程从来不能直接与Windows窗体对象交互。Windows 窗体提供了一种公式化的机制,以使后台线程中的代码能够给Ul 线程发送消息,这样UI 线程就可以为用户更新显示了。这是通过BackgroundWorker
控件实现的。
BackgroundWorker 可以在主线程(可以更新UI)和后台线程(无法更新UI)之间安全地传递控制权。
Visual Bas ic 2008 高级编程(第5 版)