2010-01-05 3 views
5

나는 포럼을 이미 수색했지만 아무 질문도 내 문제에 부합하지 않는다고 생각합니다. ...BackgroundWorker_RunWorkerCompleted가 GUI를 업데이트하지 않는 이유는 무엇입니까?

저는 시간이 많이 걸리는 작업을 처리하기 위해 BackgroundWorker를 사용합니다. 이 작업이 끝나면 사용자가 다른 작업을 수행 할 수 있도록 단추를 사용하도록 설정해야합니다.

WPF를 사용 중이며 MVVM 패턴을 따르고 있으므로이 버튼에 직접 액세스 할 수 없습니다. Button enabled-state를 true로 나타내는 Property를 설정하는 BackgroundWorker_RunWorkerCompleted 이벤트 핸들러에서 메서드를 호출해야합니다.

단 한 가지를 제외하고 모두 제대로 작동합니다. 버튼이 예를 들어서 만 다시 그려집니다. 창을 클릭하십시오 (또는 창을 최대화하십시오 ...). 매우 성가신 나에게 하루 종일했다 그게이 문제를 없애 그러나 나는 해결책을 찾을 수 없습니다 ...

BackgroundWorker_RunWorkerCompleted 이벤트 핸들러는 다음과 같습니다

void fileLoadBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
     SetButtonToEnabled(); } 

어떻게 어떤 생각을 누군가를 가지고 이 문제를 해결하려면?

편집 :

버튼은 명령에 바인딩

:

<Button Name="btnLoadTargetFile" Command="{Binding Path=LoadTargetCommand}" .../> 

이 명령은 스미스가 자신의 블로그 (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx)에 명시된 바와 같이 RelayCommand를하고 다음과 같습니다

public RelayCommand LoadTargetCommand 
    { 
     get 
     { 
      if (loadTargetCommand == null) 
      { 
       loadTargetCommand = new RelayCommand(param => this.OnRequestLoadFile(BusinessLogic.CustomTypes.TreeType.Target), param => this.CanLoadTarget); 
      } 
      return loadTargetCommand; 
     } 
     set { loadTargetCommand = value; } 
    } 

this.CanLoadTarget은 SetButtonToEnabled()에 의해 true로 설정됩니다. 방법

편집 2 :

다음 코드는 '작동'

fileLoadBackgroundWorker.RunWorkerAsync(argumentList); 
while(fileLoadBackgroundWorker.IsBusy) 
    System.Windows.Forms.Application.DoEvents(); 
SetButtonToEnabled(); 

하지만 정말 위험하고 추한 코드의 일종입니다 ...

+0

속성을 true로 설정하면 'PropertyChanged' 이벤트가 발생합니다 (즉, viewmodel이'INotifyPropertyChanged'를 올바르게 구현합니까?)? –

+0

fileLoadBackgroundWorker.RunWorkerAsync() 이후에이 메서드를 호출하면 모든 것이 올바르게 작동하므로 문제가 아닌 것 같습니까?! – lakai

+0

호기심에서 벗어나 양식의 모양이나 테두리 (테두리 색 등)에 대한 WMI 수정을 사용하고 있습니까? –

답변

2

Althought 그것은 당신의 문제를 설명 나던, 당신은 (true로 사용 버튼을 설정 한 후) 당신의 SetButtonToEnabled 함수 호출의 끝에

System.Windows.Forms.Application.DoEvents(); 

또는

Dispatcher.Invoke(new Action(delegate { }), DispatcherPriority.Background); 

를 추가 할 수 있습니다. backgroundworker가 Complete 이벤트를 호출하는 것처럼 보이지만 GUI가 새로 고쳐지지 않습니다.

Here은 WPF의 Backgroundworker를 사용한 완전한 예입니다. 당신은 그것을보고 당신이 재료가 똑같은지 확인하고 싶을 것입니다.

Asynchronous Threading with Background Worker Object을 살펴볼 수도 있습니다. Dispatcher 및 Backgroundworker를 사용하는 좋은 예입니다.

WPF Threading Model은 체크 아웃 할 수있는 또 다른 자료입니다.

+0

귀하의 의견에 감사드립니다! 내 코드는 내가 사용하는 MVVM 패턴 때문에 버튼에 직접 액세스 할 수 없다는 것을 제외하고는 예제처럼 보입니다. – lakai

+0

SetButtonToEnabled에 대한 코드를 게시 할 수 있습니까? backgroundworker의 문제는 생각하지 않습니다. Complete가 호출되는 것을 언급 한 이래로 말입니다. 아마 당신이 메인 스레드에서하고있는 것입니다. 프로세스가 백그라운드에서 실행되는 동안 무엇을하고 있습니까? – SwDevMan81

+1

InvalidateRequerySuggested를 확인하고 싶을 수도 있습니다. http://msdn.microsoft.com/en-us/library/system.windows.input.commandmanager.invalidaterequerysuggested.aspx SetButtonToEnabled의 끝에 추가하십시오. – SwDevMan81

1

당신의 문제는 아마 아무것도가 없습니다 BackgroundWorker를 사용하십시오. 주 스레드에서 직접 SetButtonToEnabled 메서드를 호출하면 동일한 동작을 볼 수 있습니다. 이것을 시험하기 위하여 RunWorkerAsync에 1로 전화를 교환하십시오 SetButtonToEnabled.

주석 작성자 몇 명이 당신의 INotifyPropertyChanged 구현을 보면 좋은 조언처럼 들리겠다고 제안했습니다.

+0

답장을 보내 주셔서 감사합니다! 주 스레드에서 SetButtonToEnabled를 호출하면 모든 것이 잘 작동합니다 ... – lakai

+0

RunWorkerCompleted 이벤트가 발생하고 있는지 확인할 수 있습니까? 거기에 설정 한 중단 점에 히트가 있습니까? –

+0

예, 중단 점이 발생합니다. – lakai

관련 문제