2012-07-06 82 views
0

如您所知,Thread類具有IsAlive屬性。如果線程方法返回或線程被中止,則爲false。所以我有這個問題:在線程中使用Timer - IsAlive屬性爲false

我有一個Windows服務,在不同的線程中啓動幾個任務。它永久性地檢查線程的IsAlive屬性,如果它是假的 - 重新創建一個任務:

foreach (var worker in _workers) 
     _threads.Add(new Thread(worker.ProtectedRun)); 

    foreach (var thread in _threads) 
     thread.Start(); 

    while (!EventWaitHandle.WaitOne(0)) 
    { 
     for (var i = 0; i < _threads.Count; i++) 
     { 
      if (!_threads[i].IsAlive) 
      { 
       _threads[i] = new Thread(_workers[i].ProtectedRun); 
       _threads[i].Start(); 
      } 
     } 

     EventWaitHandle.WaitOne(1000); 
    } 

但一個任務具有定時器內。在ProtectedRun方法中,它啓動計時器並返回。返回方法之後 - > Thread的IsAlive屬性變爲假 - > Windows服務再次啓動線程 - >無限循環:)

public override void ProtectedRun() 
    { 
     _timer = new System.Timers.Timer(24 * 60 * 1000); 
     _timer.Elapsed += OnTimedEvent; 
     _timer.Enabled = true; 
     _timer.Start(); 
    } 

難道有人有一個想法如何處理這種情況?也許檢查線程狀態而不是IsAlive屬性?

+1

如果您不檢查線程狀態/ IsAlive,請不要讓線程終止並且不要重新創建它們,在這些區域中不會有任何問題。把線程代碼寫成循環 - 你永遠不需要爲線程狀態而掙扎,並且再次創建/終止。儘量專注於'真正的應用程序代碼',而不是線程微管理,並且你的生活將變得如此簡單:-)你真的需要一個計時器嗎?睡眠(間隔)是一個更簡單的方法,並且不涉及運行定時器的另一個池線程的信號/執行。 – 2012-07-06 11:45:42

回答

3

嗯,你是一個破碎的設計,就是這樣。

  1. 您在線程中運行任務,並在線程不再活動時重新啓動它們。好。

  2. 你有一個特定的任務立即結束,但排隊更多的工作在一個計時器。好。

壞消息是,一個任務和在第一個前提下的測試幾乎是不兼容的。

選擇:

  • 返工重新啓動邏輯或

  • 保持線程活着啓動定時器後。

  • 重做它,以便有一個特定的TASK LEVEL(非線程級別)狀態字段。

在結束時,你的一個ProtectedRun方法不受同時具有活性的工作(通過計時器)排隊返回以下規格它應。

+0

謝謝你的解釋和答案。我會做一些重新設計工作。 – 2012-07-06 11:41:46

1

發生什麼事情是你的線程(帶有定時器的線程)實際上已經成功退出。這就是爲什麼IsAlive是錯誤的。

您的定時器處理程序中執行的代碼不會在您創建的線程中執行。

請看下面的例子:

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     Thread z = new Thread(new ParameterizedThreadStart(Test)) { Name = "My new thread !" }; 
     z.Start(); 

     Console.ReadKey(); 
    } 

    private static void Test(object obj) 
    { 
     Console.WriteLine(string.Format("My name is: {0}, my ID is: {1}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId)); 

     var _timer = new System.Timers.Timer(1000); 
     _timer.Elapsed += (sender, e) => 
      { 
       Console.WriteLine(string.Format("[Timer] My name is: {0}, my ID is: {1}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId)); 
      }; 
     _timer.Enabled = true; 
     _timer.Start(); 
    } 
} 

結果:

My name is: My new thread !, my ID is: 10 
[Timer] My name is: , my ID is: 12 
[Timer] My name is: , my ID is: 12 
[Timer] My name is: , my ID is: 12 

你必須重新考慮你的應用程序的設計。你確定你需要開始一個線程,首先產生一個計時器?