2009-08-11 12 views
6

私はインターネットから何かを得るオブジェクトを呼び出すスレッドを持っています。このオブジェクトが必要なすべての情報でいっぱいになると、オブジェクトを含むイベントがすべての情報になります。イベントは、スレッドを開始したコントローラーによって消費されます。WPFのスレッドとGUIはどのように別のスレッドからオブジェクトにアクセスするのですか?

イベントから返されるオブジェクトは、ビューモデルアプローチを使用してGUIにバインドされたコレクションに追加されます。

問題は、バインドでCheckAccessを使用できないことです。メインの他のスレッドから作成されたオブジェクトを使用する問題を解決するにはどうすればよいですか?

私はメインスレッドのコレクションにオブジェクトを追加するとき、私は受信エラーがある:

CollectionViewのこのタイプは、ディスパッチャスレッドと異なるスレッドからそのSourceCollectionへの変更をサポートしていません。

このコントローラ:

public class WebPingerController 
{ 
    private IAllQueriesViewModel queriesViewModel; 

    private PingerConfiguration configuration; 

    private Pinger ping; 

    private Thread threadPing; 

    public WebPingerController(PingerConfiguration configuration, IAllQueriesViewModel queriesViewModel) 
    { 
     this.queriesViewModel = queriesViewModel; 
     this.configuration = configuration; 
     this.ping = new Pinger(configuration.UrlToPing); 
     this.ping.EventPingDone += new delPingerDone(ping_EventPingDone); 
     this.threadPing = new Thread(new ThreadStart(this.ThreadedStart)); 
    } 


    void ping_EventPingDone(object sender, QueryStatisticInformation info) 
    { 
     queriesViewModel.AddQuery(info);//ERROR HAPPEN HERE 
    } 

    public void Start() 
    { 
     this.threadPing.Start(); 
    } 

    public void Stop() 
    { 
     try 
     { 
      this.threadPing.Abort(); 
     } 
     catch (Exception e) 
     { 

     } 
    } 

    private void ThreadedStart() 
    { 
     while (this.threadPing.IsAlive) 
     { 
      this.ping.Ping(); 
      Thread.Sleep(this.configuration.TimeBetweenPing); 
     } 
    } 
} 

答えて

6

これ以上の解決策が見つかりました。blog

スレッドからオブジェクトを追加するためにコレクションを呼び出す代わりに。

queriesViewModel.AddQuery(info); 

メインスレッドをコントローラに渡し、ディスパッチャを使用する必要があります。ガードの答えはとても近かった。

public delegate void MethodInvoker(); 
    void ping_EventPingDone(object sender, QueryStatisticInformation info) 
    { 
     if (UIThread != null) 
     { 

      Dispatcher.FromThread(UIThread).Invoke((MethodInvoker)delegate 
      { 
       queriesViewModel.AddQuery(info); 
      } 
      , null); 
     } 
     else 
     { 
      queriesViewModel.AddQuery(info); 
     } 
    } 
+1

このコンテキストでUIThreadの定義を投稿できますか?ありがとう。私のコードでそれを何に置き換えるべきかわからない。 – Para

+1

同じ質問。 UIThreadはどういう意味ですか? – zero51

+0

'System.Windows.Threading.DispatcherObject'のサブクラスである必要があります。 – Jalal

3

ソリューションは、メインスレッド上のオブジェクトを初期化するだろうか?

MyObject obj; 

this.Dispatcher.Invoke((Action)delegate { obj = new MyObject() }); 

編集:2回目のリードスルーでは、これはおそらく、あなたのモデルに与えられたソリューションではありません。実行時エラーがそのまま表示されますか?返すオブジェクトが独自のものである場合、オブジェクトがスレッドセーフであることを確認すると、CheckAccessが不必要になる可能性があります。

+0

このタイプのCollectionViewでは、Dispatcherスレッドとは異なるスレッドからのSourceCollectionの変更はサポートされていません。 –

関連する問題