2011-07-08 7 views
0

私はC#.NETでWinFormsアプリケーションを作成しており、ワーカースレッドからリストビューを更新したいと考えています。私はここでこれについてのすべてのポストを読んだことがあるが、Invokeとdelegateの使用を完全には理解していない。実際、ここでのいくつかの例は、静的関数から非静的なコントロールを呼び出すことで文句を言うので、コンパイルされません。静的メソッドからメンバ変数にアクセスしますか?

私はListListItemを持っています。これはAddListItem(...)を介してUIスレッドに渡したいだけです。これを行う最善の方法は何ですか?現時点では

私は、これは静的関数であるMyForm::AddListView()からである

this.lvcontrol.Invoke(new Action(() => lvcontrol.Items.Add(item))); 

を持っています。しかしもちろん、コンパイラは静的メソッドから "this"または単に "lvcontrol"を呼び出すことはできないと不平を言っています。メソッドが静的でない場合は、Formのメンバ関数である静的ワーカースレッドからメソッドを呼び出すことはできません。

+0

なぜ 'MyForm.AddListView'は静的ですか? – Richard

+0

私は静的なスレッドメソッドから呼び出すことができます – Jonnster

+0

なぜスレッドメソッドは静的ですか? –

答えて

2

あなたが更新しようとしているコードをコードが認識できるようにするには、lvcontrolへの参照が必要です(開いた形式のコピーを2つ持つことができます)。

lvcontrolが可変である場合、それはあなたのコードは、すべてのどちらかになるだろうされていない場合は、初め例えば

lvcontrol.Invoke(new Action(() => lvcontrol.Items.Add(item)) 

でこれをドロップする非静的である必要はあります。または、参照を渡す必要がありますFRMフォーム潜在

frm.lvcontrol.Invoke(new Action(() => frm.lvcontrol.Items.Add(item)) 
+0

私はすでに "this"を削除しようとしていましたが、非静的フィールドにオブジェクト参照が必要であると不平を言うだけです。 – Jonnster

+0

これは、lvcontrolがあなたのクラスのフィールドであることを意味します.... –

0

への参照である場合には周りのフォーム(これの代わりに、その参照を使用して、例えばに、マルチスレッド環境での静的データを持つ多くのトラブルがあります。例えば、一つのスレッド場合(ビューを表示するために)アイテムのコレクションを反復処理しています。他のスレッドがコレクションを変更している場合、例外が発生します。

読み取りと更新を同時に使用するマルチスレッド領域からコードを確認して静的キーワードを削除し、さらにデータを追加する必要があります(concurrency handling)。

0

を制御するconcurrent collectionをお勧めします。アプリケーション全体を通してフォームへの参照を渡すのは良い考えではありません。

ConcurrentBag<T>またはObservableCollection<T>のいずれかを使用することをお勧めします。

0

ワーカースレッドが、ワーカーがListViewのデータを渡すために使用できるUIスレッドからコールバックを渡し、コールバックに実際のListView更新を実行させる。

関連する問題