2009-08-25 4 views
41

thread.Abort 메서드를 사용하여 스레드를 강제 종료하지만 작동하지 않습니다. 스레드를 종료하는 다른 방법이 있습니까? 내가 이것을 사용하고 있지만, 때마다 내가 Alive 상태를 가져C#에서 스레드를 즉시 죽이는 방법은 무엇입니까?

private void button1_Click(object sender, EventArgs e) 
{ 
    if (Receiver.IsAlive == true) 
    { 
     MessageBox.Show("Alive"); 
     Receiver.Abort(); 
    } 
    else 
    { 
     MessageBox.Show("Dead"); 
     Receiver.Start(); 
    } 
} 

, Receiver 내 글로벌 스레드입니다.

+10

위험, Will Robinson, Danger! Thread.Abort를 사용하는 것은 매우 수줍어합니다 ** - 거의 항상 나쁜 생각입니다. –

+4

그러면 스레드를 죽이기 위해 사용해야 할 것은 무엇입니까? – Mobin

+3

스레드에게 중지하도록 요청하고 그 시점의 스레드를 무시하십시오. – MSalters

답변

58

언어 디자이너가 다음과 같은 문제를 피하고자하기 때문에 스레드를 죽이는 것이 어려운 이유가 있습니다. 스레드가 잠금을 해제 한 다음 해제하여 해제 할 수 있기 때문입니다. 그 자물쇠가 필요한 사람은 이제 붙어 있습니다.

당신이해야 할 일은 전역 변수를 사용하여 스레드가 멈추도록하는 것입니다. 스레드 코드에서 전역 변수를 수동으로 확인하고 반환해야하는 경우 중지해야 함을 나타냅니다.

+0

이 메커니즘을 직접 사용합니다. UI 기반 코드의 경우 전역 변수를 설정하고 서비스의 경우 데이터베이스 테이블을 확인합니다. 멋지고 예측 가능합니다. –

+5

가능하면 변수 대신에 ManualResetEvent를 사용하십시오. –

+3

지금 궁금한데, 조기 종료 조건을 확인하기 위해 ManualResetEvent가 어떻게 뛰어난가? 나는 우리가 무언가를 막아야 할 때 더 나아 졌다고 이해하지만, 여기에는 차단이 없다. – redtuna

6

스레드는 작업이 끝나면 죽을 것이므로 루프 나 다른 것을 사용하고 있다면 스레드를 끝내기 위해 변수를 스레드로 전달해야합니다.

4

C# Thread.Abort는 스레드를 즉시 중단하지 않을 수도 있습니다. 그것은 쓰레드가 Abort를 스스로 호출 할 때 작동하지만 쓰레드가 다른 쓰레드를 호출 할 때는 작동하지 않을 것이다.

설명서를 참조하십시오 : http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx 나는 하드웨어와 상호 작용 도구를 쓰는이 문제에 직면 한

- 당신이 즉시 정지를 원하지만이 보장되지 않습니다. 일반적으로 스레드에서 실행중인 코드의 일부가 실행되지 않도록하기 위해 일부 플래그 나 기타 논리를 사용합니다 (중단 할 때 실행하기를 원하지 않습니다).

14

먼저 합의한 스레드 종료 방법을 사용해야합니다. 예를 들어 스레드가 검사하고 준수 할 수있는 실행 가능한 값입니다.

기본 스레드 코드는 종료시 스레드를 깨끗하게 정리할 ThreadInterruptException 및 ThreadAbortException을 모두 포착하는 예외 블록에 래핑되어야합니다.

ThreadInterruptException의 경우에는 running_ 변수를 검사하여 계속해야하는지 확인할 수 있습니다. ThreadAbortException의 경우 즉시 정돈하고 스레드 프로 시저를 종료해야합니다.

다음을 수행해야 스레드를 중지하려고 코드 :

running_ = false; 
threadInstance_.Interrupt(); 
if(!threadInstance_.Join(2000)) { // or an agreed resonable time 
    threadInstance_.Abort(); 
} 
+2

내 생각에 받아 들일 수있는 유일한 대답입니다. 예, 먼저 스레드가 종료 될 수 있음을 알리는 변수가 필요하지만 스레드 내부를 차단하는 경우에는 해당 변수를 확인할 기회가 없을 수 있습니다. 차단 된 스레드를 중단하는 또 다른 방법이 필요하며이 대답이 내 문제를 해결했습니다. 감사! – CramerTV

+0

'threadInstance_.Interrupt()'가 스레드를 빨리 끝내면,'threadInstance_.Join'는 * System.Threading.ThreadStateException을 던질 것입니다 : 스레드가 시작되지 않았습니다 * – Hannobo

24

당신은 그런 식으로 그 일을 즉시 죽일 수 :

private Thread _myThread = new Thread(SomeThreadMethod); 

private void SomeThreadMethod() 
{ 
    // do whatever you want 
} 

[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] 
private void KillTheThread() 
{ 
    _myThread.Abort(); 
} 

난 항상 그것을 사용하고 나를 위해 작동합니다 :)

+0

하지만 http://stackoverflow.com/a/1560567/199364를보십시오 thread.abort가 위험한 이유를 설명하는 다른 답변 – ToolmakerSteve

+2

[Adrian Regan의 답변] (http://stackoverflow.com/a/1327377/199364)은 스레드가 죽지 않는 최후의 수단으로'Abort'를 사용하는 훨씬 안전한 방법입니다. – ToolmakerSteve

-1
private void ResumeButton_Click(object sender, RoutedEventArgs e) 
    { 
     Task.Factory.StartNew(() => 
     { 
      Application.Current.Resources["AutoPilotThreadStatus"] = true; 
      Thread.CurrentThread.Name = "ResumeAutoPilot"; 
      Thread.CurrentThread.IsBackground = true; 
      AutoPilotHandler.ResumeAutoPilot(); 
     }); 
    } 

    public static void ResumeAutoPilot() 
    { 
     while ((bool)Application.Current.Resources["AutoPilotThreadStatus"]) 
     { 
      CheckAutoPilotThreadStatus(); 
      var searchYoutube = YoutubeHandler.Search("small truck"); 
      CheckAutoPilotThreadStatus(); 
      SaveVideosToDatabase(searchYoutube); 
      CheckAutoPilotThreadStatus(); 
     } 
    } 

    public static void CheckAutoPilotThreadStatus() 
    { 
     if (!(bool)Application.Current.Resources["AutoPilotThreadStatus"]) 
     { 
      KillCurrentThread(); 
     } 
    } 

    public static void KillCurrentThread() 
    { 
     Thread.CurrentThread.Abort(); 
    } 
+3

앱 리소스 사용 방법에 대한 완벽한 예입니다. –

관련 문제