1

スレッドの保持で実行されているプロセスの実行を開始および停止するWindowsサービスがあります。

次の2つのクラスがあります。

public class PerformTask
{
    Thread _thread = null;
    public void StartTask()
    {
        _thread = new Thread(new ThreadStart(DoSomeWork));
        _thread.Start();
    }

    public void DoSomeWork()
    {
        // Do Some Work
        _thread = null;
    }

    public void Abort()
    {
        if (_thread != null)
        {
            try
            {
                _thread.Abort();
            }
            catch (ThreadAbortException) {}
        }
    }
}

public class Engine
{
    List<PerformTask> _task = new List<PerformTask>();
    public void Start()
    {
        var task = new PerformTask();
        _task.Add(task);
        // Add task to the timed action queue
        _actionQueue.Add(s => task.StartTask(), TimeSpan.FromSeconds(10));
    }

    public void Stop()
    {
        _task.ForEach(task => task.Abort());
        _task.Clear();
        _actionQueue.Stop();
        _actionQueue.Clear();
    }
}

_actionQueueは、指定された繰り返し時間間隔で指定されたアクションを実行するために開発されたカスタム定義のソースコードです。すべてのアクションはキューに保持され、指定された時間間隔で呼び出されます。

これで、WindowsサービスのOnStartメソッドとOnStopメソッドは、それぞれEngineクラスのStartメソッドとStopメソッドを呼び出します。

私が欲しいのは、Windowsサービスが停止したときに、実行中のすべてのスレッドが処理/実行を停止する必要があることです。

しかし、ここで起こっているのは、新しいスレッドインスタンスが作成されているときに、スレッドの保持で実行されているプロセスの実行を開始および停止するWindowsサービスがあります。

次の2つのクラスがあります。

public class PerformTask
{
    Thread _thread = null;
    public void StartTask()
    {
        _thread = new Thread(new ThreadStart(DoSomeWork));
        _thread.Start();
    }

    public void DoSomeWork()
    {
        // Do Some Work
        _thread = null;
    }

    public void Abort()
    {
        if (_thread != null)
        {
            try
            {
                _thread.Abort();
            }
            catch (ThreadAbortException) {}
        }
    }
}

public class Engine
{
    List<PerformTask> _task = new List<PerformTask>();
    ActionQueue _actionQueue = new ActionQueue();
    public void Start()
    {
        foreach(.....)
        {
            var task = new PerformTask();
            _task.Add(task);
            // Add task to the timed action queue
            _actionQueue.Add(s => task.StartTask(), TimeSpan.FromSeconds(10));
        }
        _actionQueue.Start();
    }

    public void Stop()
    {
        _task.ForEach(task => task.Abort());
        _task.Clear();
        _actionQueue.Stop();
        _actionQueue.Clear();
    }
}

ActionQueueは、指定された時間間隔で指定されたアクションを実行するために開発されたカスタム定義のソースコードです。すべてのアクションはキューに保持され、指定された時間間隔で呼び出されます。

これで、WindowsサービスのOnStartメソッドとOnStopメソッドは、それぞれEngineクラスのStartメソッドとStopメソッドを呼び出します。

私が欲しいのは、Windowsサービスが停止したときに、実行中のすべてのスレッドが処理/実行を停止する必要があることです。

しかし、ここで起こっているのは、StartTaskメソッドで新しいスレッドインスタンスが作成されているためです。_task.ForEach(task => task.Abort())を呼び出すと、スレッドの正しいインスタンスがありません。つまり、すべてのインスタンスです。 of _thread = new Thread(....); 同じPerformTaskクラスに複数のキューがあるため、はアクセスされていません。

注:ActionQueueを変更できません。

  1. Abortメソッドはスレッドを停止する正しい方法ですか?

  2. すべてのスレッド(ソースコードによって作成されたThreadクラスのすべてのインスタンスを含む)を停止するにはどうすればよいですか?

4

1 に答える 1

1

WaitHandle通常、次のような(ManualResetEventたとえば)を作成します。

ManualResetEvent stopAllThreads = new ManualResetEvent(false);

したがって、イベントは「設定されていません」。すべての作業が完了するか、手動リセットイベントが設定されるまでループするように、スレッドメソッドのループを変更します。

while (!stopAllThreads.WaitOne(50))

または類似。

次に、サービスのOnStopメソッドで、イベントを設定するだけです(で再度リセットすることを忘れないでくださいOnStart。そうしないと、サービスの再起動時にスレッドが再度実行されません)。

stopAllThreads.Set();

すべてのスレッドが終了するのを待ちます。

実際、スレッドを中止することはスレッドを停止するための良い方法ではありません-あなたは常に上記のようなものに行くべきです。

于 2012-05-11T08:02:28.087 に答える