2016-11-04 2 views
0

내 코드에 문제가 있습니다. 메인 양식이있는 그래픽 응용 프로그램을 만드는 중입니다. 단추를 클릭하면 일부 파일을 내보내는 동안 진행률 막대를 표시하는 새 양식을 만듭니다. 내 문제는 어떻게 진행 파일 표시 줄을 사용하여 양식을 닫으려고 할 때 어떤 파일을 내보낼 지 끝나지 않기 때문에 시작됩니다.닫을 때 스레드에서 메소드 실행 중지

새 형식에서는 내보내기 진행률을 확인하고 진행률 표시 줄을 채우는 메서드를 실행합니다.이 메서드는 매초마다 실행됩니다. 내보내려면 새 스레드를 만들고이 스레드는 내보내기 메서드를 실행합니다.

내보내기가 완료되면 양식과 스레드가 올바르게 닫히지 만 양식을 닫아 작업을 강제 종료하면 내보내기가 끝날 때까지 또는 기본 양식을 닫을 때까지 내보내는 스레드가 멈추지 않습니다.

그래서 어떻게 그 스레드를 멈출 수 있습니까?

public Form3(File file, string output, string inputFile) 
    { 
     InitializeComponent(); 
     this.file = file; 
     this.output = output; 
     this.inputFile = inputFile; 
     progressLabel.Location = new Point(textProgress.Right, progressLabel.Top); 
     thread = new Thread((ThreadStart)delegate { Exporter.ExportToFile(this.file, this.output, this.inputFile); }); 
     thread.IsBackground = true; 
     thread.Start(); 

     TimerControl(); 


    } 

    private void TimerControl() 
    { 
     System.Windows.Forms.Timer t = new System.Windows.Forms.Timer(); 
     t.Tick += new EventHandler(GetProgress); 
     t.Interval = 1000; // in miliseconds 
     t.Start();  

    } 

    private void GetProgress(object sender, EventArgs myEventArgs) 
    { 
     int x = Exporter.GetProgress(); 
     progressBar.Maximum = 100; 
     if (!Exporter.stop) 
     { 
      progressBar.Value = x; 
      progressLabel.Text = x.ToString() + "%"; 
     } 
     else 
     { 

      this.Close(); 

     } 
    } 
+0

이것을 올바르게하려면, 'Exporter.ExportToFile()'에 취소 지원을 추가해야한다. –

+0

잔인하지만 다소 효과적 :'Closing' 이벤트 'thread.Abort()'를 호출하십시오 - 물론 다른 방법도 좋습니다. –

+0

그건 끔찍한 충고입니다. ['절대로 Thread.Abort()를 호출하지 마십시오]] (http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort). –

답변

0

것은 여기에 이해하기 : "내보내기 파일에"것을 실행하는 코드 (Exporter.ExportToFile) ... 는 중지에 기록되지 아마

이 내 코드입니다.

즉, 해당 구성 요소를 향상 시키려고합니다. 그런 맥락에서 그것을 사용한다는 것은 정말로 당신이 당신의 수출업자에게 또 다른 방법을 추가하고 싶다는 것을 의미합니다; "AbortExport"또는 이와 비슷한 것!

(대신 예를 들어, 기본 스레드를 죽이는 - 당신은 수출에 의해 생성 된 모든 파일을 예를 들어 삭제됩니다 보장 할 수 있습니다, 그리고 모든 관련 자원 적절한 정리를 볼 수 있음)

0

사용하지 왜 대신 작업? 하여 OperationCanceledException을 던지고 그것을 취소가 요청 된에 토큰을 전달하여 https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

에서

인용. 이 작업을 수행하는 가장 좋은 방법은 ThrowIfCancellationRequested 메서드를 사용하는 것입니다. 이 방법으로 취소 된 작업은 취소 된 상태로 전환되며, 호출 코드는 작업이 취소 요청에 응답했는지 확인하는 데 사용할 수 있습니다. https://msdn.microsoft.com/en-us/library/dd997364(v=vs.110).aspx

에서

인용 협동 제거 모델을 구현하는 일반적인 패턴이다

  • 관리하는 개별 소거 토큰에 해소 통지를 송신하는 CancellationTokenSource 객체를 인스턴스화한다.

  • 취소를 수신 대기하는 각 작업 또는 스레드에 CancellationTokenSource.Token 속성에서 반환 한 토큰을 전달하십시오.

  • 각 작업 또는 스레드가 취소에 응답하는 메커니즘을 제공하십시오.

  • 취소 알림을 제공하려면 CancellationTokenSource.Cancel 메서드를 호출하십시오.

당신은 Thread.Abort(); 방법을 사용할 수 있습니다 첫 번째 기사

0

에서 샘플 코드를 참조하지만, 스레드를 중단 할 최적/안전 방법이 아니다.

스레드를 종료하는 가장 안전한 방법은 .. 적절한 시간에 종료하여 수출 클래스에 추가 코드를 추가하는 것입니다

당신은 스레드를 안전하게 종료해야한다고 나와 함께 동의 그 유래에 대한 답변의 톤을 찾을 수 있습니다 사용자 코드에 의해.

편집 : Thread.Abort(); 나쁜 생각인데, 원래 대답에서 분명하다고 생각했다.

+1

[아니요, 절대로'Thread.Abort()'] (http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort)를 사용해서는 안됩니다. 이것은 매우 나쁜 조언입니다. "당신은 항상 Thread.Abort()"를 사용할 수있는 것이 아니라 "당신은 Thread.Abort()"를 사용해서는 안됩니다. –

+0

@MatthewWatson, 전체 답변을 읽었습니까? 또는 대답을 downvoting 느꼈다? – Yahfoufi

+0

예 전체 답변을 읽었지만 첫 번째 문장에는 여전히 'Thread.Abort(); 방법'. 당신은 당신이 "항상"그것을 사용할 수 있다고 말함으로써 대답을 시작하지 말고 그 방법을 결코 사용해서는 안된다는 것을 분명히해야합니다. 왜 그것이 나쁜 생각인지 알 수 없습니까? 그 문장 전체를 제거하거나 마지막 부분으로 옮기고 "Thread.Abort()'를 사용해서 절대로 스레드를 중단해서는 안된다. –

관련 문제