microsoft mobile 移動應用開發寶典----讀書筆記(11)

 多線程編程,自由編程(free-threaded)
概念:調度(scheduling)、競態條件(race condition)、線程關聯(thread affinity)、死鎖(deadlock)、臨界區(critical section)同步對象、線程池(thread pool)、計時器(timer)

1.爲什麼使用線程
線程使程序代碼複雜化,但是獲得較好的吞吐能力throughput和響應速度responsiveness
掛起hang:及時響應用戶接口的維護

2.理解底層機制
多任務multitasking:同一時間段內運行多個進程
多線程multithreading:每個進程能夠同時執行多個任務
.NET Framework引入了一個概念上的輕型進程--應用程序域(Application Domain.AppDomain)

1)Windows CE
一個進程:主線程(primary thread或main thread)
  次線程(secondary thread)或工作線程(worker thread)
操作系統由時間片段輪轉(round-robin)方式運行線程
線程都有一其自身的堆棧、一個CPU寄存器副本和一片線程局部存儲區(Thread-Local Storage,TLS)
線程運行持續一段預置的時間長度----線程擁有的“時間總量(thread quantum)”,或時間片段(context switch)
線程調度----線程優先級
.NET Compact Framework程序的默認線程

2) System.Threading
鼠標右鍵“解析”
Synchronization Fuctions:msdn2.microsoft.com/en-us/library/aa302340.aspx#win32map-aynchronizationfunctions
內存屏障memory barriers
靜態方法MemoryBarrier:msdn2.microsoft.com/en-us/library/system.threading.memorybarrier.aspx
新類型 Semaphore www.daniel,oth.com/Blog/2005/01/semaphore.html
  EventWaitHandle www.danielmoth.com/Blog/2005/01/eventwaithandle.html

3.及時響應用戶接口的維護
1)消息泵message pump
消息----消息隊列(消息泵)----.NET事件----主線程

2)耗時的任務
用一個工作線程來及時響應UI

3)演示示例

4)不理想的解決方案
Refresh方法
DoEvents方案:處理隊列中所有的消息,繼續執行DoEvents後面的代碼(會產生重入代碼reentrant code的問題)

5)使用線程來解決問題
System.Windows.Forms.Timer----輪詢(polling)技術  (不完美)
Thread.Join(不推薦用在主線程上)
UI線程的規範:盡在創建UI元素的線程上操作它們----Windows對象具有線程親和性(thread affinity),
             
強調:不要在工作線程中操作UI控件
      讓方法知道它們是由主線程、工作線程調用的,通過檢查Control.InvokeRequired屬性
Control.Invoke
死鎖(deadlock):主線程被阻塞,等待工作線程的結束,其間,工作線程也等待主線程處理由Invoke方法發出的自定義Windows消息。相互等待,結果都不繼續執行。
解決:工作線程完成任務後,讓主線程得到通知,以便主線程可以將最終的結果更新到UI上

6)BackgroundWorker組件
相關示例:www.danielmoth.com/Blog/2004/12/backgroundworker-sample.html

4.線程活動的同步與數據訪問
線程的弊端:死鎖、競態條件(race condition)
1)競態條件
多個線程同時訪問同一塊數據
Ildasm.exe反彙編
說明:高級語言寫成的代碼在運行時會被拆成多行代碼,調度程序(scheduler)可能在任意位置進行上下文切換(context switching)
原子性(atomic)

2)監視器monitor
臨界區(critical regions):保護併發訪問的代碼區,每次只能有一個線程進入的代碼區域

3)線程安全thread safe
線程安全:可以安全的在多個線程中被調用的方法
框架方法----實例方法
集合類

4)再論死鎖
精心設計:徹底掌握線程在各處的執行情況,線程之間能夠通信

5) ManualResetEvent
線程間的通信與協議
AutoResetEvent
Mutex(互斥鎖),.NET Compact Framework中不能使用

5. ThreadPool線程池
需要指定一個委託,這個委託還要接受一個object類型的狀態

6.理解線程與程序的關閉
主窗體退出標誌着程序的結束(程序沒有創建任何線程)----當所有後臺(foreground)線程都推出後,程序纔會結束

1)後臺線程
前臺線程----顯示創建的線程
後臺線程----來自ThreadPool或由框架創建的線程
除非用戶操作,則使用的線程都應爲後臺線程
設置爲後臺線程的方法:線程被啓動前,IsBackground屬性設置爲true,爲其命名,這兩個屬性納入構造過程
平臺調用服務PInvoke

2)線程的終止
Abort方法強行退出(不推薦)
聲明工作線程和主線程都可見的布爾變量

7.使用.NET計時器
System.Threading.Timer由來自ThreadPool線程觸發
注意:保留一個計時器對象的引用,符合垃圾回收的條件
      使用完後,釋放
      參數

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