创建基于Windows Mobile设备的多线程应用程序

适用于: 

·         Microsoft Visual Studio® 2005

·         Microsoft .NET Compact Framework version 2.0

·         Microsoft Windows CE 5.0

·         基于Windows Mobile 5.0版本的Pocket PC软件

一、先建单线程应用程序:

创建新的空白 Pocket PC 应用程序。

1.      启动 Microsoft Visual Studio® 2005,点击 Start | All Programs | Microsoft Visual Studio 2005 | Microsoft Visual Studio 2005。

2.      选择 File | New Project。

3.      确认 Project types对话框中的Visual C# Projects | Smart Device | Windows Mobile 5.0 Pocket PC被选择。

4.      确认Templates中,Device Application 已被选择。

5.      在 Name 对话框中,输入 MultithreadedApp 作为应用名称。

6.      在 Location 对话框中,输入C:\Program Files\Windows Mobile Developer Samples\HOLs\HOL328_Multithreaded_NETCF2_Apps。

确认 Create directory for solution被选中,如图 1所示 。

 

图1:新建项目对话框

 

点击OK 创建该程序,如图2:

 

图2:Visual Studio 2005中的一个新建Pocket PC项目

虽然您并没有做太多的工作,但是这时候,Visual Studio已经帮您创建了一个完整的Pocket PC应用了。

生成解决方案并发布到模拟器

1.      选择 Start Debugging | Debug。

2.      在 Deploy MultithreadedApp 对话框中,确认Windows Mobile 5.0PocketPCEmulator被选中,点击Deploy,如图 3所示。

 

图3:MultithreadedApp应用程序部署窗口

Visual Studio 2005将显示进度。发布完成后,您将可以在模拟器中看到您的程序被启动,目前这个程序还没有任何功能,我们接下来会添加相关的代码。

为应用程序添加功能

1.      选择Debug | Stop Debugging 结束程序。

2.      在Properties窗口 中,将窗体的Text 属性修改为Multithreaded App。

3.      将 Minimize Box 属性修改为 false。

4.      现在,我们来添加多线程的功能代码。

5.      从toolbox拖拽一个button控件到form。

6.      修改这个button的Text 属性为Begin processing。

7.      双击 Begin processing 按钮创建事件处理函数。

8.      将下面的代码添加到 button1_Click 方法中。

button1.Enabled = false;

 

processingDone = false;

 

BackgroundProcessing();

9.      回到设计模式,从toolbox拖拽一个button控件到form。

10.    将这个button的Text 属性修改为End processing。

11.    双击End processing 按钮创建事件处理函数。

12.    将下面的代码添加到 button2_Click 方法中。

processingDone = true;

button1.Enabled = true;

 

13.    将下面的代码添加到 Form1.cs 的开头。

using System.Threading;

 

14.    为Form1 添加bool类型的变量processingDone:

 

private bool processingDone = false;

 

15.      为 Form1 添加下面的BackgroundProcessing 方法。

private void BackgroundProcessing()

{

    while (! processingDone)

    {

        Thread.Sleep(0);

    }

}

16.      选择Debug | Start Debugging 运行程序。

17.      在 Deploy MultithreadedApp 对话框中,确认Windows Mobile 5.0 Pocket PC Emulator被选择,然后点击Deploy。

18.      在模拟器中,点击应用程序的Begin processing 按钮。

19.      您会看到这时 Begin processing 按钮被禁用了。

20.      点击 End processing 按钮结束程序。

21.      此时程序失去响应了。这是因为所有的操作都是在同一线程中完成的,所以在sleep的时候无法响应button2_Click事件。如图 4所示。

 

图4:应用程序正在运行但是不能停止

为了解决这个问题,您需要在分开的线程中运行 BackgroundProcessing 方法。

 

二、修改多线程应用程序

在本练习中,您将修改练习1中创建的应用程序。创建一个新的线程,并将 BackgroundProcessing方法放到这个线程中。

结束停止响应的程序,选择Debug | Stop Debugging 结束程序。

为 BackgroundProcessing 的执行创建新方法

1.      在processingDone声明的下方添加一个名为workerThread 的Thread 类型的私有变量。

private Thread workerThread;

2.      将button1_Click 方法中BackgroundProcessing() 的调用语句替换成下面的代码。

workerThread = new Thread(BackgroundProcessing);

workerThread.Start();

您必须调用Start 方法才能让新的线程开始运行。

3.      选择Debug | Start Debugging。

4.      选择 Windows Mobile 5.0 Pocket PC Emulator并点击 Deploy。

5.      在模拟器运行的程序中,点击 Begin processing 按钮。

您会看到 Begin processing 按钮被禁用了。

6.      点击应用程序的 End processing 按钮。

您会看到 Begin processing 按钮又重新可以响应了。这次,您可以控制程序了。

Properly Terminating Created Threads

在 .NET Compact Framework 2.0中,后台线程会和前台线程有所不同。我们现在来看看有什么不同。

1.      在模拟器中,点击 Begin processing 按钮。

2.      点击程序右上角的 OK。

看起来程序结束了,但是实际上, Visual Studio 显示程序仍然在运行。原因是创建的后台线程仍然在运行。下面我们添加代码,用来提示用户在退出前结束工作线程。

3.      选择Debug | Stop Debugging。

4.      在Visual Studio 2005中,切换到设计视图,选中Form1。

5.      在Properties窗体中,点击 Events 按钮。

6.      双击Closing事件,如图5所示。

图5:添加一个窗体关闭的事件处理

 

7.      在 Form1_Closing 事件处理方法中添加下面的代码。

if (!processingDone)

{

    MessageBox.Show("Terminate the worker thread before closing the application");

    e.Cancel = true;

}

8.      选择Debug | Start Debugging 运行程序。

9.      确认选择目标设备为 the Windows Mobile 5.0 Pocket PC Emulator,点击 Deploy。

10.      在模拟器中,点击 Begin processing。

11.      点击窗体右上角的 OK。

12.      此时程序在不结束 BackgroundProcessing 线程之前是不会关闭的。

13.      点击 End Processing 按钮后点击 OK。

在 .NET Compact Framework 2.0中,您可以设置工作线程的IsBackground 属性为true,这样在程序退出时会自动地结束所有工作线程。现在,我们做相应的修改。

14.      在Visual Studio 2005中切换到Form1.cs 的设计视图。

15.      选中Form1,在 Properties 窗体中点击 Events 按钮。

16.    右键单击 Closing 事件并选择 Reset。

17.    将 Form1_Closing 方法从 Form1.cs 中删除。

18.      在 button1_Click 中创建和开始线程的代码之间插入下面的语句:

workerThread.IsBackground = true;

19.      使用快捷键 F5 开始调试程序。

20.      确认目标设备为Windows Mobile 5.0 Pocket PC Emulator,点击 Deploy。

21.      在模拟器中,点击 Begin processing 按钮。

22.      点击右上角的OK。

这一次,程序在 BackgroundProcessing 线程运行时也可以正常退出了。

判断工作线程是否真正被结束

有的时候,一个线程并没有被真正结束,我们需要加入判断。

1.      定位到Form1.cs中的 BackgroundProcessing 方法。在while循环下方,加入下面的代码:

Thread.Sleep(2000);

2.      定位到 button2_Click 方法,在processingDone = true 语句下方加入如下代码:

workerThread.Join();

3.      运行程序。

4.      点击 Begin processing 按钮后点击End processing 按钮。

您会发现Begin processing 按钮过几秒钟以后才会变亮。原因是我们的程序在等待工作线程停止。

5.      关闭程序。

使用 Thread.Abort 终止线程

在本任务中,我们学习使用Thread.Abort 方法终止线程。

1.      在button2_Click 方法中定位到processingDone = true 并将该语句替换成下面的代码:

workerThread.Abort();

2.      使用下面的代码替代 BackgroundProcessing 方法中的原有代码:

private void BackgroundProcessing()

{

    try

    {

        while (!processingDone)

        {

            Thread.Sleep(0);

        }

    }

    catch (ThreadAbortException e)

    {

        MessageBox.Show(e.Message);

    }

    finally

    {

        // This deinitialization code must always be executed,

        // so be sure to put it in a finally clause.

        Thread.Sleep(2000);

    }

}

运行程序。

3.      点击 Begin processing 按钮后点击End processing 按钮。

您将会看到 ThreadAbortException 异常被抛出,在处理异常后工作线程被停止。

线程优先级

在Windows CE操作系统中,线程是分优先级的,改变线程的优先级将动态的影响到程序的运行。我们接下来将把工作线程的优先级调整到比主线程高。

注意 永远不要在真实应用中这样做。

1.      将BackgroundProcessing 方法中的Thread.Sleep(0)语句替换成分号。

2.      运行程序。

3.      点击 Begin processing 按钮后点击 End processing按钮。

4.      退出程序。

现在我们看到主线程能够顺利的结束工作线程因为它们运行在同一个优先级上。我们来看看如果把工作线程的优先级调整以后会发生什么。

5.      在 button1_Click方法中定位到workerThread.Start() ,在该语句上方添加下面的代码。

workerThread.Priority = ThreadPriority.AboveNormal;

6.      运行程序。

7.      点击 Begin processing 按钮后点击End processing 按钮。

您现在可以看到,不是非常容易停止工作线程了,而且它的行为是不可预知的。原因是工作线程拥有比主线程更高的优先级,“阻止”了主线程的运行。现在只能通过Visual Studio 来停止这个程序。

8.      在Visual Studio 2005中使用快捷键 SHIFT+F5 停止调试。

到现在为止我们已经比较了后台线程和前台线程。


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值