2015-09-02 187 views
0

我有一個類,它實現了一個無盡的工作線程,如this例子,在我的情況下代表一個機構。在運行期間,我將在任何時間處於0到8個實例之間,實例不斷被創建和銷燬。無盡工作線程的線程池

大多數情況下,這個類的生命週期爲30秒到5分鐘,但偶爾可能會有一些在相對較短的時間內創建和銷燬的實例。鑑於這些代碼運行在低規格硬件上,我傾向於遇到性能問題。

我現在想要重寫行爲,以便我使用ThreadPool來處理正在運行的工作集合,並且我正在努力尋找構建代碼的正確方法。

基本上我有此刻的代碼是一樣的東西

public class BodyCollection : IReadOnlyDictionary<ulong, TrackedBody> 
{ 
    public void Update() 
    { 
     if (createNew) 
     { 
      var body = new TrackedBody(); 
      body.BeginTracking(); 
      this.Add(1234, body); 
     } 

     if (remove) 
     { 
      TrackedBody body = this[1234]; 
      body.StopTracking(); 
      this.Remove(body); 
     } 
    } 
} 

public class TrackedBody 
{ 
    private readonly Thread _BiometricsThread; 
    private volatile bool _Continue = true; 

    public TrackedBody() 
    { 
     _BiometricsThread = new Thread(RunBiometricsThread); 
    } 

    public void BeginTracking() 
    { 
     _BiometricsThread.Start(); 
    } 

    public void StopTracking() 
    {  
     _Continue = false; 
    } 

    private void RunBiometricsThread() 
    { 
     while(_Continue) 
     { 
      System.Threading.Thread.Sleep(1000); 
     } 
    } 
} 

那麼,如何重新寫上正確,所以利用線程池,當需要我可以取消其上運行的線程池線程?我是否使用CancellationTokens或ManualResetEvents來控制線程?

+1

你只是不這樣做,像這樣的線程對線程池是有害的。它們阻止其他t​​p線程及時得到服務。合理的最大值是半秒,除此之外,它開始堵塞管道非常糟糕。不要這樣做。 –

+0

@HansPassant我明白了......如果即使您的應用程序是在給定設備上運行的唯一應用程序,您是否會說上述方法是正確的? –

+0

這與應用程序沒有任何關係,它是關於線程的。 –

回答

1

我堅信你應該使用更現代的異步編程方法。我們要在這裏使用任務並行庫,因爲它給你你想要的免費功能:

  • 跟蹤完成
  • 取消
  • 線程池

public class TrackedBody 
{  
    public Task BeginTrackingAsync(CancellationToken cancellation) 
    { 
     return Task.Run(() => RunBiometricsThread(cancellation)); 
    } 

    private void RunBiometricsThread(CancellationToken cancellation) 
    { 
     while(!cancellation.IsCancellationRequested) 
     { 
      Task.Delay(1000, cancellation); 
     } 
    } 
} 

請注意,我已刪除async關鍵字。這沒有做任何事情。

您可以使用該任務來跟蹤正在進行的工作的狀態。您可以使用取消令牌來停止所有工作。

+0

async關鍵字只是一個錯字。我知道它自己什麼都不做,但對於你的其他例子,這可能會起作用,我會用這種方法來玩,並且好奇創建多個任務的表現。我會認爲它應該比線程更快。我可以發誓我在某些時候嘗試過類似的東西,但它在我的語境中沒有起作用(因此我回到傳統線索的原因),但會再次以新的面貌再次看。非常感謝您的意見 –

+0

@MaximGershkovich線程池的優點是創建和註冊線程的相對昂貴的操作已經完成。沒有其他優點和一些缺點 - 超額訂購和線程本地存儲的脆弱性。 – Gusdor