有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'DataGridView' がアクセスされました。

シェアする

  • このエントリーをはてなブックマークに追加

DataGridViewを作成したスレッド以外からColumn追加しようとするとこんなエラーが出ました。

有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'dataGridView2' がアクセスされました。

WS000011

マルチスレッドの観点からスレッドセーフでない呼び出しを行うとこのようなエラーが出るようです。
Javaだとよくロックして困ったのですが、C#ではエラーがわかりやすいです。

スポンサードリンク

簡単なスレッドセーフでない呼び出しのサンプリアプリケーション

Formにボタンとテキストボックス2個を追加しただけの簡単なサンプルを考えます。

WS000019

ボタンを押した後、別のスレッドでテキストボックスをフォーカスしてみます。

実行するとこんなエラーが出ます。

WS000020

型 'System.InvalidOperationException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました

追加情報: 有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'textBox2' がアクセスされました。

コントロールを作成したスレッド以外から、このコントロールをフォーカスすることは許されないようです。

スポンサードリンク

フォームコントロールのスレッドセーフな呼び出し方法

Invoke(new delegate())を使って、上記のプログラムを書き換えてみます。

WS000021

delegate void delegate1()というメソッドはスレッドセーフな呼び出しが可能となりました。
引数も取ることが可能です。

スポンサードリンク

まとめ

いかがでしたでしょうか?

スレッドセーフなプログラミングは、C++でもJavaでもいつも悩ましかったのです。

JavaのGUIコンポーネントであるSwingはシングルスレッド設計であり、Swing は常に一つのスレッドからのみアクセスすることを意識しないといけませんでした。

そのため、Javaでちょっと凝ったことをするとよくロックしてしまっていたのですが、C#は実行時にわかりやすくエラーが出る上に、Invoke(new delegate())をすれば、そのスレッドで動かすことが可能です。

最後まで読んでいただきありがとうござました。

この記事が気に入っていただけたらシェアしてくれると嬉しいです。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です