2011-02-09 11 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

ビジーウェイト:

は、私はいくつかのことを試してみました自分で問題を解決するために、

すべての試行で同じ結果が得られました。画面が更新される前にスクリーンショットが実行されました。わたしが考え出したタイマーの使用で、のADD_ITEMが実行された後に画面は更新されてになります。ですから、私はコンパイラがいくつかの暗黙的なスレッドを作成し、それを修正/防止する方法を知らないことを提案します。

ありがとうございました。

+0

愚かな仮定のため申し訳ありません...スクリーンショットの前にSystem.Windows.Forms.Application.DoEvents()を数回試しましたか? –

+0

また、別のスレッドでスクリーンショットを作成してみてください。最初にDoEventsを呼び出し、ThreadPool.QueUserWorkItemで新しいスレッドを開始します。 –

答えて

1

私はそのようなことをしなければならないときは、常にすべてが処理された後に起動するタイマーイベントを使用します。あなたが持っているそのように

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

それを発射する:

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

何行われる必要があるが、ここではこのようなものになりますワンショットタイマイベントと使用になりますメッセージループがすべてを行い、スクリーンの更新がタイマーが始まる前に終了するという良いチャンスです。

+2

'System.Windows.Forms.Timer'を使用している場合は、ペイントが終了していることが保証されます。それはWindowsの中で最も低い「優先度」のメッセージであるフードの下の 'WM_TIMER'に解決されます。これは、経過したタイマーがある場合や、何もする必要がなければ 'GetMessage'によって合成されます。 –

関連する問題