創建基於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 停止調試。

到現在爲止我們已經比較了後臺線程和前臺線程。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章