2012-07-06 23 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 

你必须重新考虑你的应用程序的设计。你确定你需要开始一个线程,首先产生一个计时器?

相关问题