2012-01-23 7 views
2

私は、他の誰かが市場データを取得したサービスを使用しています。サーバーに接続し、シンボルを送信してデータを返します。さて、複数のビューを開いて、複数のシンボルのマーケットデータを取得できるように、このビューを使用しようとしています。これが行われる方法は、私のViewModelがSingletonイベントIncomingMessageにサブスクライブし、メッセージにViewModelのシンボルが含まれている場合、ObservableCollectionにそれを入れます。それが問題の原因です。C#シングルトンUIスレッディング問題

イベントからのメッセージを自分のコレクションに安全に追加するにはどうすればよいですか?

[編集] ObservableCollectionが私のビューのDataGridにバインドされているため、例外がスローされていると思います。

+1

あなたは、ビューとビューモデルをどのようなテクノロジで参照していますか? ASP.NET MVC? – StriplingWarrior

+0

ロックキーワードが役立たないのですか? http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx – rskar

+0

MVVM with WPF。私はObservableCollectionを私のビューにバインドしていると思います。 – Stephen

答えて

3

UIスレッドへのAddメソッドの呼び出しをマーシャリングする必要があります。プリズムでは、これは通常、イベントアグリゲータで行われていますが、プリズムを使用していない場合:

はあなたの市場データを表し、いくつかのタイプTickを持っていると仮定すると、データイベントがちょうどSystem.Action<Tick>であること:

dataSource.IncomingMessage += (tick) => Application.Current.Dispatcher.Invoke(new Action<Tick>(AddTheTick), tick); 

または、単に

dataSource.IncomingMessage += (tick) => Application.Current.Dispatcher.Invoke(new Action<Tick>(myObservableCollection.Add), tick); 
+0

"静的でないフィールド、メソッド、またはプロパティに 'オブジェクト参照が必要です。' System.Windows.Threading.Dispatcher.Invoke(System.Delegate、params object []) '"私が受け取ったデータを検証する必要があるからです。 – Stephen

+0

'Application.Current.Dispatcher'を使用してください - それに応じて編集します –

+0

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

3

ObservableCollection<T>は、一般的に、バックグラウンドスレッドから更新することはできません。コレクションが属するスレッドにデータが確実に追加されるようにするには、Dispatcher.Invoke()またはDispatcher.BeginInvoke()を使用する必要があります。

static class ObservableCollectionExtensions 
{ 
    internal static void InvokeAdd<T>(this ObservableCollection<T> self, T item) 
    { 
     Application.Current.Dispatcher.Invoke((Action<T>)self.Add, item); 
    } 

    internal static void BeginInvokeAdd<T>(this ObservableCollection<T> self, T item) 
    { 
     Application.Current.Dispatcher.BeginInvoke(new Action<T>(self.Add), item); 
    } 
} 

そのように安全なことができますいくつかのキーストロークを、代わりにこれを入力します:かなり一般的なタスクだ

Application.Current.Dispatcher.Invoke((Action)(() => myObservableCollection.Add(value))); 

、それはあなたのためにこれの世話をするための拡張メソッドを作成するために価値がある

myObservableCollection.InvokeAdd(value); 
+0

ありがとう、私はそれを行います。 – Stephen

関連する問題