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サービスが停止しているとき、実行中のすべてのスレッドが処理/実行を停止する必要があることです。

しかし、新しいスレッドインスタンスはタスク開始の方法で作成されているとして何をここで起こっていることですが、私は_task.ForEach(タスク=> task.Abort()) を呼び出すときに、私はスレッドの正しいインスタンスを持っていません、それはすべて のインスタンスです_thread = new Thread(....); は、同じPerformTaskクラスに対して複数のキューが存在するため、アクセスされていません。

注:ActionQueueを変更することはできません。

  1. スレッドを停止する正しい方法はありますか?

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

+0

私は質問する必要があります - あなたは明示的にスレッドを停止する必要がありますか?明示的に停止しないと、どうなりますか? –

答えて

1

通常、あなたはそのようWaitHandle(例えばManualResetEvent)を作成したい:

ManualResetEvent stopAllThreads = new ManualResetEvent(false); 

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

while (!stopAllThreads.WaitOne(50)) 

または類似のもの。

stopAllThreads.Set(); 

:次に、サービスのOnStop方法では、あなたは、単にイベントを(サービスを再起動すると、それ以外のスレッドが再び実行されません、OnStartで再びそれをリセットすることを忘れないでください)設定

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

実際には、スレッドを中止するのは良い方法ではありません。いつも上記のようなことをする必要があります。

+0

あなたの答えをありがとう。しかし、ここで問題となるのは、WindowsServiceはEngineクラスのみにアクセスし、プロジェクトの要件に応じて、WindowsServiceの停止が呼び出されると、実行中のスレッドはすべて終了し、実行を続行しなくてはなりません。すべてのスレッドが終了するのを待つべきではありません。 ManualResetEventを使用してその状況をどのように達成できますか? –

+0

さて、 'ManualResetEvent'は' Engine'クラスに組み込まれ、 'Stop'メソッドで設定されるべきです。スレッドが瞬間的に停止する場合は、スレッドの実行内で「ステップ」を定義し、次のステップが実行されるかどうかを確認する必要があります。おそらくあなたの場合、Tasksと 'CancellationToken'を使うほうが簡単でしょう。 –

関連する問題