これをもう一度突き刺してみましょう...
1.) ListView をフォームにドラッグします。
2.) BackgroundWorker をフォームにドラッグします。
3.) ListViewItem コレクションを反復処理するメソッドを作成する
private void LoopThroughListItems()
{
foreach (ListViewItem i in listView1.CheckedItems)
DoSomething();
}
4.) BackgroundWorker の DoWork イベント内で LoopThroughListItems() を呼び出すコードを追加します。
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
LoopThroughListItems();
}
5.) フォーム ロードで - メイン スレッド (動作) でコードを実行し、次に backgroundWorkder スレッド (失敗) でコードを実行します。
private void Form1_Load(object sender, EventArgs e)
{
// Try it on the UI Thread - It works
LoopThroughListItems();
// Try it on a Background Thread - It fails
backgroundWorker1.RunWorkerAsync();
}
6.) IsInvokeRequired/Invoke を使用するようにコードを変更します。
private void LoopThroughListItems()
{
// InvokeRequired == True when executed by non-UI thread
if (listView1.InvokeRequired)
{
// This will re-call LoopThroughListItems - on the UI Thread
listView1.Invoke(new Action(LoopThroughListItems));
return;
}
foreach (ListViewItem i in listView1.CheckedItems)
DoSomething();
}
7.) アプリを再度実行します。これで、UI スレッドと非 UI スレッドで動作します。
それは問題を解決します。IsInvokeRequired/Invoking のチェックは、慣れ親しんだ一般的なパターンです (これが、すべてのコントロールに含まれている理由です)。あちこちでそれを行っている場合は、ここで説明されているように、巧妙なことをしてすべてをまとめることができます: InvokeRequired コードパターンの自動化