0

ご存知かもしれませんが、Thread クラスには IsAlive プロパティがあります。スレッド メソッドが返された場合、またはスレッドが中止された場合は false です。だから私はこれに問題があります:

異なるスレッドでいくつかのタスクを開始する Windows サービスがあります。スレッドの IsAlive プロパティを永続的にチェックし、false の場合はタスクを再作成します。

    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);
    }

しかし、タスクの 1 つにタイマーが含まれています。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. すぐに終了する特定のタスクがありますが、タイマーでさらに作業をキューに入れています。良い。

ただし、悪いニュースは、最初の前提の下での 1 つのタスクとテストには互換性がないということです。

選択肢:

  • 再起動ロジックを作り直すか、

  • タイマーを開始した後、スレッドを存続させます。

  • 特定の TASK LEVEL (スレッド レベルではない) ステータス フィールドが続くように修正します。

最後に、あなたの 1 つの 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 に答える