2011-02-09 3 views
1

다음과 같은 문제가 있습니다. 내 응용 프로그램이 화면 업데이트를 수행 한 후 새보기의 스크린 샷을 만들어야합니다. 다음과 같이
코드는 다음과 같습니다C# 화면 업데이트와의 동기화

public ViewModelBase Screen { 
     get { 
      if (_screen == null) { 
       Screen = new DataSourceChooserScreenViewModel(this); 
       History.ChangeHistory(ADD_ITEM); 
      } 
      return _screen; 
     } 
     set { 
      _screen = value; 
      OnPropertyChanged("Screen"); 

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

화면 업데이트는 "OnPropertyChanged를 ("화면 ")"에서 수행하고 스크린 샷은 "History.ChangeHistory (ADD_ITEM)"에서 가져온 것입니다.

//Do something 
Screen = otherScreen; 
History.ChangeHistory(ADD_ITEM); 
//Do something else 

을 그리고 여기에 문제는 다음과 같습니다 : "화면"에 대한 세터를 호출
방법은 모두 같은 계획에 따라 실행 순서가 다른 것을 말한다 있지만 화면이 업데이트되기 전에 스크린 샷이 만들어진다. BeginInvoke() 및 EndInvoke()의
사용을 통해 PropertyChangedEvent에서 대기로 ADD_ITEM에 타이머에 의해 비동기 스레딩의
사용 대기 ADD_ITEM

통화 중 대기 :

내가 몇 가지를 시도 혼자서 문제를 해결하려면 012.Wayows.Forms.Application.DoEvents()

모든 시도가 동일한 결과를 얻었습니다. 스크린 샷이 업데이트되기 전에 스크린 샷이 완료되었습니다. 알아 낸 타이머를 사용하기 위해 ADD_ITEM을 수행 한 후 화면이 업데이트 됨 입니다. 그래서 컴파일러가 암시적인 스레딩을하고 그것을 수정/방지하는 방법을 모르겠다.

도움 주셔서 감사합니다.

+0

어리석은 가정에 대해 ... 스크린 샷 전에 System.Windows.Forms.Application.DoEvents()를 몇 번 사용해 보았습니까? –

+0

또한 다른 스레드에서 스크린 샷을 만들어보십시오. 먼저 DoEvents를 호출 한 다음 ThreadPool.QueUserWorkItem을 통해 새 스레드를 시작하십시오. –

답변

1

내가 이런 식으로해야 할 때, 나는 항상 모든 것이 처리 된 후 시작되는 타이머 이벤트를 사용합니다. 그것은 하나의 샷 타이머 이벤트가 될 것입니다 및 사용은 다음과 같이 될 것입니다 :

그것을 발사하려면 무엇이 필요하나요

Timer t=new Timer(); 
t.Tick+=DoAfter; 
t.Interval=100; 
t.Start(); 

가 여기에 있습니다 :

void DoAfter(object Sender, SomeArgs a) 
{ 
    Timer t=(Timer)Sender; 
    t.Stop(); 
    t.Dispose(); 
    // perform your stuff here 
    DoStuff(); 
} 

당신이 그 방법을 메시지 루프가 모든 것을 처리 할 수있는 좋은 기회이며 타이머 업데이트가 시작되기 전에 화면 업데이트가 완료됩니다.

+2

'System.Windows.Forms.Timer'를 사용하고 있다면, 페인팅이 완료된 것입니다. 그것은 윈도우에서 가장 낮은 "우선 순위"메시지 인 후드 아래에서 WM_TIMER로 해석됩니다. 그것은 경과 된 타이머가 있고 할일이 없다면'GetMessage'에 의해 합성됩니다. –