扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:中国IT实验室 来源:中国IT实验室 2007年10月2日
关键字:
在本页阅读全文(共2页)
我们可以创建使 UI 和辅助代码无需进行线程交互操作的体系结构。实际上我们可以实现此目标,还能实现一个能够通过某种方式实现复杂代码的架构,可以用来管理或控制后台线程及其 UI 交互。
我们先来讨论体系结构,然后再讨论如何设计和实现代码。从本文的相关链接可以下载此代码以及说明如何使用此代码的示例应用程序。
通常情况下,应用程序中首先会启动一个单一线程,来打开用户界面。我们将其命名为“UI 线程”以便于理解。“UI 线程”是许多应用程序中的唯一线程,因此它要处理 UI 并完成所有操作。
但是,现在我们创建一个“辅助线程”进行某些后台操作,让 UI 线程集中处理用户界面。这样即使辅助线程繁忙,UI 线程也可以对用户保持响应状态。
我们在 UI 线程和辅助线程之间插入一层代码,使其充当 UI 和辅助代码之间的接口。此代码实质上是一个“控制器”,用来管理和控制辅助线程及其与 UI 之间的交互。
图 1:UI 线程、控制器和辅助线程
控制器包含的代码可以安全地启动辅助线程,将任何状态消息从辅助线程中转给 UI 线程,以及将任何取消请求从 UI 线程中转回辅助线程。UI 代码和辅助代码不能直接交互,它们通常要通过控制器的代码进行交互。
但是辅助线程被激活“之前”和“之后”的时间段除外,这时 UI 代码可以与 Worker 对象进行交互。启动辅助线程之前,UI 可以创建并初始化 Worker 对象。终止辅助线程之后,UI 可以从 Worker 对象中检索任何值。从 UI 的角度看,将形成以下事件流:
除了在辅助线程处于激活状态时 UI 代码无法与 Worker 对象直接交互的限制外,对 UI 没有特殊的编码要求。即使正在运行后台操作,UI 也会对用户保持激活和响应状态。从 Worker 对象的角度看,将形成以下事件流:
由于辅助代码只与 Controller 交互,因此我们不必担心辅助线程会意外地与 UI 组件交互(这无疑会使应用程序不稳定)。现在,辅助代码依靠 Controller 与 UI 线程进行正确通信,因此各项操作都很安全。这意味着,只要处理好 Worker 对象中的实例变量,就无需处理辅助代码中的任何线程问题。
使用图表通常能够很好地了解不同组件(尤其是不同线程上的组件)之间的交互。Microsoft® Visio® 支持创建 UML(通用建模语言)图表,对理解很有帮助。
以下是说明 UI、Worker 对象和 Controller 之间事件流的 UML 序列图表。此图表假设不存在任何取消操作请求。Worker 和 Controller 对象下面重叠在垂直线上的垂直活动栏突出了辅助线程上运行的代码。其他所有代码都在 UI 线程上运行。
图 2:说明进程流的序列图表
使用 UML 活动图表也可以查看事件流。这种图表形式的着重点在于任务而不是对象,因此其中显示了发生的一系列步骤以及各步骤之间的流程。我们很容易看出 UI 代码如何停留在左侧的线程中,而 Worker 对象如何在右侧的线程上工作。Worker 对象在其他线程中运行之前和运行之后可以直接由 UI 使用,以便初始化值,然后再检索结果。
图 3:显示进程流的活动图表
使用这样的图表可以帮助我们找出后台线程处于激活状态时,UI 与辅助线程(或反过来)无意中进行直接交互的位置。任何这样的交互都需要额外地进行编码,以避免出现可能使应用程序不稳定的错误。理想状态下,这种交互通过 Controller 组件来实现,我们可以在其中包含所有编码,使交互安全进行。
下图说明了 UI 发出取消请求时的事件序列。
图 4:显示取消请求的序列图表
请注意,取消请求从 UI 发送到 Controller,然后 Worker 线程与 Controller 进行核实,确定是否发生了取消请求。UI 和 Controller 都不会强制辅助代码终止,而是允许辅助代码自己正常安全地终止
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者