熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

基於.NET的多線程編程入門

2022-06-13   來源: .NET編程 
多線程在構建大型系統的時候是需要重點關注的一個重要方面特別是在效率(系統跑得多快?)和性能(系統工作正常?)之間做一個權衡的時候恰當的使用多線程可以極大的提高系統性能

什麼是線程?

   每個正在系統上運行的程序都是一個進程每個進程包含一到多個線程進程也可能是整個程序或者是部分程序的動態執行線程是一組指令的集合或者是程序的特殊段它可以在程序裡獨立執行也可以把它理解為代碼運行的上下文所以線程基本上是輕量級的進程它負責在單個程序裡執行多任務通常由操作系統負責多個線程的調度和執行

什麼是多線程?

   多線程是為了使得多個線程並行的工作以完成多項任務以提高系統的效率線程是在同一時間需要完成多項任務的時候被實現的

使用線程的好處有以下幾點

   ·使用線程可以把占據長時間的程序中的任務放到後台去處理

   ·用戶界面可以更加吸引人這樣比如用戶點擊了一個按鈕去觸發某些事件的處理可以彈出一個進度條來顯示處理的進度

   ·程序的運行速度可能加快

   ·在一些等待的任務實現上如用戶輸入文件讀寫和網絡收發數據等線程就比較有用了在這種情況下我們可以釋放一些珍貴的資源如內存占用等等

   還有其他很多使用多線程的好處這裡就不一一說明了

一些線程模型的背景

   我們可以重點討論一下在Win環境中常用的一些模型

   ·單線程模型

   在這種線程模型中一個進程中只能有一個線程剩下的進程必須等待當前的線程執行完這種模型的缺點在於系統完成一個很小的任務都必須占用很長的時間

   ·塊線程模型(單線程多塊模型STA)

   這種模型裡一個程序裡可能會包含多個執行的線程在這裡每個線程被分為進程裡一個單獨的塊每個進程可以含有多個塊可以共享多個塊中的數據程序規定了每個塊中線程的執行時間所有的請求通過Windows消息隊列進行串行化這樣保證了每個時刻只能訪問一個塊因而只有一個單獨的進程可以在某一個時刻得到執行這種模型比單線程模型的好處在於可以響應同一時刻的多個用戶請求的任務而不只是單個用戶請求但它的性能還不是很好因為它使用了串行化的線程模型任務是一個接一個得到執行的

   ·多線程塊模型(自由線程塊模型)

   多線程塊模型( MTA )在每個進程裡只有一個塊而不是多個塊這單個塊控制著多個線程而不是單個線程這裡不需要消息隊列因為所有的線程都是相同的塊的一個部分並且可以共享這樣的程序比單線程模型和STA的執行速度都要塊因為降低了系統的負載因而可以優化來減少系統idle的時間這些應用程序一般比較復雜因為程序員必須提供線程同步以保證線程不會並發的請求相同的資源因而導致競爭情況的發生這裡有必要提供一個鎖機制但是這樣也許會導致系統死鎖的發生

多線程在NET裡如何工作?

   在本質上和結構來說NET是一個多線程的環境有兩種主要的多線程方法是NET所提倡的使用ThreadStart來開始你自己的進程直接的(使用ThreadPoolQueueUserWorkItem)或者間接的(比如StreamBeginRead或者調用BeginInvoke)使用ThreadPool類一般來說你可以手動為長時間運行的任務創建一個新的線程另外對於短時間運行的任務尤其是經常需要開始的那些進程池是一個非常好的選擇進程池可以同時運行多個任務還可以使用框架類對於資源緊缺需要進行同步的情況來說它可以限制某一時刻只允許一個線程訪問資源這種情況可以視為給線程實現了鎖機制線程的基類是SystemThreading所有線程通過CLI來進行管理

   ·創建線程

   創建一個新的Thread對象的實例Thread的構造函數接受一個參數



Thread DummyThread = new Thread( new ThreadStart(dummyFunction) );

   ·執行線程

   使用Threading命名空間裡的start方法來運行線程

DummyThreadStart ();

   ·組合線程

   經常會出現需要組合多個線程的情況就是當某個線程需要其他線程的結束來完成自己的任務假設DummyThread必須等待DummyPriorityThread來完成自己的任務我們只需要這樣做

DummyPriorityThreadJoin() ;

   ·暫停線程

   使得線程暫停給定的秒

DummyPriorityThread Sleep (<Time in Second>);

   ·中止線程

   如果需要中止線程可以使用如下的代碼

DummyPriorityThreadAbort();

   ·同步

   經常我們會遇到需要在線程間進行同步的情況下面的代碼給出了一些方法

using System;using SystemThreading;namespace SynchronizationThreadsExample{
  class SynchronizationThreadsExample{
   private int counter = ;
static void Main( ) {
    SynchronizationThreadsExample STE = new SynchronizationThreadsExample();
    STEThreadFunction( );
   }
   public void ThreadFunction ( ) {
    Thread DummyThread = new Thread( new ThreadStart(SomeFunction) ;
    DummyThreadIsBackground=true;
    DummyThreadName = First Thread;
    DummyThreadStart( );
    ConsoleWriteLine(Started thread {} DummyThreadName);
    Thread DummyPriorityThread = new Thread( new ThreadStart(SomeFunction) );
    DummyPriorityThreadIsBackground=true;
    DummyPriorityThreadName = Second Thread;
    DummyPriorityThreadStart( );
    ConsoleWriteLine(Started thread {} DummyPriorityThreadName);
    DummyThreadJoin( );
    DummyPriorityThreadJoin( );
   }
   public void SomeFunction( ) {
    try {
     while (counter < ) {
      int tempCounter = counter;
      tempCounter ++;
      ThreadSleep();
      counter = tempCounter;
      ConsoleWriteLine( Thread {} SomeFunction: {}ThreadCurrentThreadName counter);
     }
    }
    catch (ThreadInterruptedException Ex) {
     ConsoleWriteLine( Exception in thread {} ThreadCurrentThreadName);
    }
    finally {
     ConsoleWriteLine( Thread {} Exiting ThreadCurrentThreadName);
    }
   }
  }
}

   ·使用Interlock

   C#提供了一個特殊的類叫做interlocked就是提供了鎖機制的實現我們可以加入如下的代碼實現鎖機制

InterlockedSomeFunction (ref counter);

   ·使用鎖

   這是為了鎖定代碼關鍵區域以進行同步鎖定代碼如下

lock (this){ Some statements ;}

   ·使用 Monitor

   當有需要進行線程管理的時候我們可以使用

MonitorEnter(this);


   其他也有一些方法進行管理這裡就不一一提及了

線程的缺點

   線程自然也有缺點以下列出了一些

   ·如果有大量的線程會影響性能因為操作系統需要在他們之間切換

   ·更多的線程需要更多的內存空間

   ·線程會給程序帶來更多的bug因此要小心使用

   ·線程的中止需要考慮其對程序運行的影響

   ·通常塊模型數據是在多個線程間共享的需要一個合適的鎖系統替換掉數據共享
From:http://tw.wingwit.com/Article/program/net/201311/13467.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.