2010-08-23 2 views
0

C# 4.0에서 병렬 프로그래밍을 테스트하는 프로그램을 만들었습니다. 그러나 문제가 있으며 이유를 파악할 수 없습니다.디버깅이 디버깅없이 실행되는 것과 다른 이유는 무엇입니까 (작업 취소)?

나는 별도의 스레드 (UI 스레드가 아닌)에서 실행하는 방법

private void compute(int startValue, int endValue, ConcurrentBag<Pair> theList) 
    { 
     try 
     { 
      Task computation = Task.Factory.StartNew(() => { findFriendlyNumbers(startValue, endValue, theList, tokenSource.Token); }, tokenSource.Token); 
      Task.WaitAll(computation); 
      StringBuilder builder = new StringBuilder(); 
      foreach (Pair p in theList) 
      { 
       builder.AppendLine(p.ToString()); 
      } 

      this.textBlockResult.Dispatcher.Invoke(new Action(() => 
      { 
       this.textBlockResult.Text = builder.ToString(); 
       this.progressBar1.Visibility = System.Windows.Visibility.Hidden; 
      })); 
     } 
     catch (AggregateException aEx) 
     { 
      MessageBox.Show("Entering"); //For debug, but never runs 
      aEx.Handle(handleCancelling); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

에게 물품.

그리고 (단순화 된)에 함수 tokenSource 해제시 캐치 블록하지 않는 것처럼

 private void findFriendlyNumbers(int start, int end, ConcurrentBag<Pair> list, CancellationToken token) 
    { 
     //some initialization and computation 

     for (int i = start; i <= end; i++) 
     { 
      //check whether it's cancelled 
      token.ThrowIfCancellationRequested(); 

      //some computation 
     } 
    } 

문제는, "하여 OperationCanceledException는 사용자 코드에 의해 처리되지 않은"오류가있을 것이다 있다. 이유는 모르겠습니다. 내 코드가 교과서 나 MSDN과 비슷하기 때문입니다.

감사합니다.

편집 : 사실 한 달 전에 비슷한 프로그램을 작성했는데 모든 것이 잘되었습니다. 오늘 다시 시도해 보니 같은 문제가 발생했습니다. 프로그램을 마친 후에 Microsoft Visual Web Developer 2010 Express를 설치했는데 이유가 확실하지 않습니다. 나는 그것, 동일한 부호, 다른 결과를 얻지 않는다.

편집 : 이 문제에 대해 생각해 보니 어디가 잘못되었는지 알았습니다. 과거에는 디버그를 사용하는 동안 "디버깅하지 않고 실행"을 사용했습니다. 디버깅없이 실행하면 문제가 해결됩니다. 누군가가 왜 디버그가 "디버그없이 실행"과 다른지 알려주면 감사하겠습니다.

답변

1

취소 토큰을 TaskFactory.StartNew 방법으로 전달 중입니다. 이로 인해 Task이 특별히 처리됩니다. 오류 대신 취소 표시가됩니다.

토큰을 매개 변수로 TaskFactory.StartNew에 전달하지 않으면 오류로 처리되어 캐치됩니다. 매개 변수로 유지하는 경우 예외 대신 Task.IsCanceled을 사용하여 취소를 확인해야합니다.

사이드 노트 : Invoke을 사용하여 UI 스레드와 동기화하지 않는 것이 가장 좋습니다. I have an example of Task objects properly doing UI progress updates on my blog.

+0

정말 고마워요.하지만 진짜 문제는 아닙니다. http://msdn.microsoft.com/en-us/library/dd997396.aspx를 참조하십시오. IsCancellationRequested를 간단하게 확인할 수 있지만 작업을 중지하기 위해 예외를 사용하지 않으면 작업 상태가 RanToComplete로 유지됩니다. – LLS

+0

내 대답을 다시 읽으십시오. 'Task.IsCanceled'가 아니라 'CancellationToken.IsCancellationRequested'입니다. –

+0

죄송합니다. 토큰 인수를 제거하려고 시도했지만 결과는 같습니다. 그리고 작업을 확인하는 방법을 잘 모르겠습니다. 먼저 작업을 취소 할 방법이없는 경우 취소했습니다. – LLS

관련 문제