0

您可能知道 Thread 类具有 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);
    }

但是其中一项任务里面有 Timer。在 ProtectedRun 方法中,它启动计时器并返回。返回方法后 -> 线程的 IsAlive 属性变为 false -> windows 服务再次启动线程 -> 无限循环 :)

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

有人知道如何处理这种情况吗?也许检查线程状态而不是 IsAlive 属性?

4

2 回答 2

3

好吧,你的设计很糟糕,就像那样。

  1. 您在线程中运行任务并在它们不再存在时重新启动它们。好的。

  2. 您有一个特定任务立即结束,但在计时器上排队了更多工作。好的。

不过,坏消息是,一个任务和第一个前提下的测试根本不兼容。

选择:

  • 重做重启逻辑或

  • 启动计时器后保持线程处于活动状态。

  • 重做它,以便有一个特定的任务级别(不是线程级别)状态字段可以遵循。

最后,您的一个 ProtectedRun 方法没有遵循它应该在有活动工作排队时返回的规范(通过计时器)。

于 2012-07-06T11:25:10.073 回答
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

您必须重新考虑应用程序的设计。您确定需要首先启动一个产生计时器的线程吗?

于 2012-07-06T11:32:13.437 回答