2016-04-11 13 views
0

これは説明が少し難しいかもしれませんが、私はベストを尽くします。ディスパッチャーは正しくトリガーされません。Application.Current.Dispatcher.Invoke

環境はWPF MVVMアプリケーションです。

クラスの一つが含まれています: ...

public ObservableCollection<Rat> Rats { get; set; } 

を...

public void UpdateRats(int nbRats) 
     { 
      try 
      { 
       if (nbRats > 0) 
       { 
        for (int i = 0; i < nbRats; i++) 
        { 
         Application.Current.Dispatcher.Invoke(() => Rats.Add(new Rat())); 
         // Application.Current.Dispatcher.BeginInvoke( new Action(() => Rats.Add(new Rat() ))); 
         // Rats.Add(new Rat()); 
        } 
       } 
       if (threadSimul != null && !threadSimul.IsAlive) 
       { 
        threadSimul = new Thread(new ThreadStart(simul)); 
        threadSimul.Start(); 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 

UpdateRatsは、このオブジェクトを作成したスレッドによって呼び出されると、すべてが正常に動作します。 別のスレッドから呼び出されると、ディスパッチャの呼び出し時に実行が停止したように見えます。 Application.Current.Dispatcher.Invoke(()=> Rats.Add(new Rat()));

ステップバイステップデバッグでスレッドを終了する証拠は表示されませんが、デバッガはこのスレッドでのアクティビティの表示を停止します。 スレッドはまだ生きていますが、何も起こりません。

ディスパッチャーを誤って呼び出すことはできますか?

何らかの理由がありますか?

は、該当する場合は、2番目のスレッドがこのように作成されます。

threadSimul = new Thread(() => simul()); 
      threadSimul.SetApartmentState(ApartmentState.STA); 
      threadSimul.Start(); 

をし、サイマルは含まれています。事前に

... 
    UpdateRats(n); 
... 

Thxをします。

答えて

0

私は前にこの種の問題に直面しました。通常、あなたのメソッドの外にディスパッチャを作成することによって、それは動作します。あなたのコンストラクタでそれを作成しようとします。次のようなものがあります。

private Dispatcher _dispatcher; 

public class RatManager() 
{ 
    _dispatcher = Dispatcher.CurrentDispatcher; 
} 

私は、ループを作成するたびにDispatcher.Invokeメソッドを呼び出しません。これは私がここにBeginInvokeメソッドを使用してい

// Assuming you already created a Dispatcher variable 
_dispatcher.BeginInvoke(() => 
{ 
    // Loop here 
} 

注意(少なくとも私にとっては)良くなります。同期処理を特に必要としない限り、BeginInvokeはUIスレッドをブロックしないため常に良好です。

+0

提案と同じ結果です。とにかくThx。 –

関連する問題