1

스레드 보유와 함께 수행되는 일부 프로세스의 실행을 시작하고 중지하는 Windows 서비스가 있습니다.스레드가 더 이상 처리하지 못하도록 중지가 완료되면

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 서비스가 있습니다.

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 호출 할 때

는하지만, 여기에서 일어나고있는 것은, 새로운 스레드 인스턴스가 StartTask 방법에서 생성되는 것입니다 (작업 => task.Abort는()) 나는 스레드의 올바른 인스턴스가 없습니다 , 그것은 모두 의 인스턴스입니다. _thread = new Thread (....); 은 동일한 PerformTask 클래스에 대해 여러 큐가 있으므로 액세스되지 않습니다.

참고 : ActionQueue를 변경할 수 없습니다.

  1. 올바른 방법으로 스레드를 중지 할 수 있습니까?

  2. 모든 스레드 (소스 코드로 작성된 스레드 클래스의 모든 인스턴스 포함)를 중지하려면 어떻게합니까?

+0

내가 물어야한다 - 명시 적으로 스레드를 중지해야합니까? 명시 적으로 중지하지 않으면 어떻게됩니까? –

답변

1

보통은 그런 WaitHandle (예를 들어 ManualResetEvent)를 만들 것입니다 :

ManualResetEvent stopAllThreads = new ManualResetEvent(false); 

그래서 이벤트 "로 설정하지"입니다

. 스레드 메소드의 루프를 변경하여 모든 작업이 완료되거나 수동 재설정 이벤트가 설정 될 때까지 반복합니다.

while (!stopAllThreads.WaitOne(50)) 

또는 이와 유사한 것.

그런 다음 서비스의 OnStop 방법, 당신은 단순히 (서비스가 다시 시작될 때 다른 스레드가 다시 실행되지 않습니다, OnStart 다시 재설정하는 것을 잊지 마세요) 이벤트를 설정합니다

stopAllThreads.Set(); 

모든 스레드가 완료 될 때까지 기다립니다.

실제로 스레드를 중지하는 것은 스레드를 중지하는 좋은 방법이 아닙니다. 항상 위와 같은 방법을 사용해야합니다.

+0

답변 해 주셔서 감사합니다. 그러나 여기서 문제는 WindowsService가 Engine 클래스에만 액세스하고 프로젝트 요구 사항에 따라 WindowsService 중지가 호출되면 실행중인 모든 스레드가 종료되어야하며 더 이상 실행을 계속해서는 안됩니다. 모든 스레드가 완료 될 때까지 기다리지 않아야합니다. ManualResetEvent를 사용하여 그 상황을 어떻게 달성 할 수 있습니까? –

+0

그럼,'ManualResetEvent'는'Engine' 클래스에 통합되어'Stop' 메소드에서 설정되어야합니다. 스레드를 즉시 중지하려면 스레드 실행 내에서 "단계"를 정의하고 다음 단계가 실행될 수 있는지 확인해야합니다. 아마 당신의 경우 Tasks와'CancellationToken'을 사용하는 것이 더 쉬울 것입니다. –

관련 문제