| | | .NET Framework 精简版后台处理技术 | | 2003-05-10·
· ··Mirosoft
| 上一页 1 2 3 4 下一页 显式创建的线程
有些情况下,后台进程(例如连续读取全球定位系统或监视设备)会占用应用程序的大部分运行时间。在这些情况下,最好为特定的任务创建专用的线程。
专用线程通过 Thread 类的实例实现,并通过将方法包装到 ThreadStart 委托,将此委托传递给 Thread 类构造函数,然后调用 Thread.Start 方法来创建。
void ReadGPSFeed() { // 循环读取 GPS 数据 }
public void btnStartGPS_Click(object sender, EventArgs e) { ThreadStart startMethod = new ThreadStart(ReadGPSFeed); Thread gpsThread = new Thread(startMethod); gpsThread.Start(); // 启动后台线程 } | 在本例中,ReadGPSFeed 方法运行在一个新创建的线程上。此线程专用于 ReadGPSFeed 方法,并在该方法退出后终止。
通过专用线程完成的工作通常是以某种循环的方式执行处理。尽管在有些情况下由后台进程本身确定处理是否完成,但更多的情况下是由某个外部事件(如用户请求或应用程序关闭)来确定。以信号方式通知后台线程终止的最简单方式是通过类级别的布尔标志,如以下代码所示:
Class MyForm : Form { // 为清楚起见,省略了部分类成员 private bool _continueGPSRead = false; // 读取控制标志 void ReadGPSFeed() { while (_continueGPSRead) // 循环,直到为 false { // 读取 GPS 数据 } } public void btnStartGPS_Click(object sender, EventArgs e) { ThreadStart startMethod = new ThreadStart(ReadGPSFeed); Thread gpsThread = new Thread(startMethod); _continueGPSRead = true; // 设置循环标志 gpsThread.Start(); // 启动后台线程 } public void btnStopGPS_Click(object sender, EventArgs e) { _continueGPSRead = false ; // 发送 ReadGPSFeed 信号以终止 } }
| 在本例中,btnStartGPS_Click 通过将标志设置为“true”并启动相关线程,以启动后台处理。ReadGPSFeed 方法继续处理,直到通过 btnStopGPS_Click 将 _continueGPSRead 标志设置为“false”为止。
后台处理和用户体验
后台处理是一个功能强大的工具,正确使用可以显著改善用户体验。但是,如果使用不当,也容易产生混乱甚至引起错误。要获得良好的用户体验,应记住以下几个要点。 不要直接影响用户界面 一个应用程序最初只启动一个线程。正常情况下,所有用户界面控件均由该线程创建。Windows CE 用户界面对象具有“线程关系”,这意味着这些界面对象与创建它们的线程紧密耦合在一起。这种紧密耦合是由于所有与 Windows CE 用户界面对象的交互(读取和更新)均依赖于创建线程所管理的消息队列。与创建线程相比,与线程中的界面对象的消息队列进行交互容易引起数据损坏或其他错误。.NET Framework 精简版中的 Windows 窗体控件是 Windows CE 用户界面对象上的简便包装,它也具有同样的限制。此限制同时适用于线程池和显式创建的线程。
要允许后台进程与用户界面进行安全的交互,所有 Windows 窗体控件都提供了一个特殊的 Invoke 方法。调用 Invoke 方法可以将控件传递给创建 Windows 窗体控件的线程,并在此线程上执行一个委托。用户界面线程中运行的方法必须包装在一个事件处理程序委托中。
class MyForm : Form { // 为清楚起见,省略了一些成员 private MathProxy _wsMath = new MathProxy(); protected TextBox _txtSum; // 将显示 XML Web Service 的结果 protected int _sum ; public void btnAdd_OnClick(object sender, EventArgs e) { AsyncCallback cb = new AsyncCallback(OnAddComplete); _wsMath.BeginAdd(10, 15, cb, null); // 启动 XML Web Service 调用 } public OnAddComplete(IAsyncResult ar) // 完成后由框架调用 { _sum = _wsMath.EndAdd(ar); // 获取 XML Web Service 结果 // 在创建 _txtSum 的线程上执行 UpdateSumDisplay _txtSum.Invoke(new EventHandler(UpdateSumDisplay)); } public void UpdateSumDisplay(object sender, EventArgs e) { _txtSum.Text = _sum.ToString(); } | 在本例中,btnAdd_OnClick 进行异步 Web 服务调用。异步调用完成后,将自动调用 OnAddComplete 方法。正如“异步 Web 服务”一节所述,OnAddComplete 方法在后台线程中运行,因此无法直接、安全地影响 _txtSum 文本框。使用 Invoke 方法,可以将控件传递给创建 _txtSum 的线程。然后,在此线程中运行 UpdateSumDisplay。
注意:Invoke 是一个中断调用。Invoke 线程将中断,直到从被调用的方法返回。
上一页 1 2 3 4 下一页 | | | 感谢
访问天极网,如果您觉得该文章涉及版权问题,请看这里!
|
|