2010-12-17 2 views
2

모든 처리가 완료된 후 Parallel.Invoke로 무거운 배경 작업을 실행하고 있습니다. 메소드를 반환하고, 다시 돌아와 계산 된 데이터를 활용하는 다음 메서드를 호출합니다. 오류 : 크로스 스레드 작업이 유효하지 않습니다. 제어가 '생성 된 스레드가 아닌 다른 스레드에서 액세스되었습니다.배경 작업을 parallel.Invoke로 실행 한 후 UI를 업데이트합니다.

하지만 처음에는 Parallel.Invoke에서 생성 한 스레드에서 이미 반환했습니다. 컨트롤이 시작된 스레드로 되돌아 가지 않는다는 것이 정상입니까? 그리고 이것이 어떻게되는지 확신 할 수 있습니까?

코드 :

public void TopMethod() 
     { 
      Calculate(4); 
      UpdateGui(); 
     } 

     public void Calculate(int depth) 
     { 
      Recursive(depth); 
     } 

     public void Recursive(int depth) 
     { 
      if (depth > 0) 
       System.Threading.Tasks.Parallel.Invoke(
          delegate { Recursive(depth - 1); }); 
     } 

     public void UpdateGui() 
     { 
      CalculateOhter(); // Works fine. 
      controlElement.Focus(); // Causes exception 
     } 

편집 : 나는 약 Control.Invoke 알고하지만이 못생긴 솔루션 (모든 컨트롤에 대리인을 저장하지 않으을) 될 프로그램은 모든 계산을 기다릴 필요 계속하기 전에 완료하십시오. 그래서 어떻게 든 컨트롤을 처음부터 함께 시작한 쓰레드로 되돌릴 수 있다면 더 좋을 것입니다.

답변

0

끔찍한 방법은 Control.CheckForIllegalCrossThreadCalls을 false로 설정하는 것입니다. 그것은 당신의 오류를 제거해야하지만, 그것은 좋은 디자인이 아닙니다.

컨트롤의 스레드를 만드는 스레드 이외의 스레드가 해당 컨트롤의 메서드 나 속성 중 하나에 액세스하려고 시도 할 때 그 문제가 발생하면 종종 예기치 않은 결과가 발생합니다.

0

Control.Invoke 예제에는 대리자를 저장하는 것과 관련된 모든 컨트롤에 대한 대리자를 저장하지 않고도이 작업을 수행 할 수 있습니까? 그래서 Invoke 호출에 인수로 호출해야하는 메서드를 전달합니다 (이 함수를 시도했지만 작동시키지 못했습니다).

프로그램이 계속 진행하기 전에 모든 계산이 완료 될 때까지 기다려야 만합니다. 어쨌든 컨트롤을 처음부터 시작한 스레드로 되돌릴 수 있다면 더 좋을 것입니다.

왜 이것이 기본적으로 발생하지 않는지 이해할 수 없습니다. 모든 것이 완료되었을 때 시작한 스레드로 돌아 가지 않는 이유는 무엇입니까?

0

해결 : 처음에는 주어진 코드를 호출하기 위해 별도의 스레드를 만들었습니다. 좀 바보 같았습니다. P

관련 문제