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

プログラミング
スポンサーリンク

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

 

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

 

 

マルチスレッドの観点からスレッドセーフでない呼び出しを行うとこのようなエラーが出るようです。

 

Javaだとよくロックして困ったのですが、C#ではエラーがわかりやすいです。

スポンサーリンク

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

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

 

 

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

 

 

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

 

 

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

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

 

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

 

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

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

 

 

 

delegate void delegate1()

というメソッドはスレッドセーフな呼び出しが可能となりました。

引数も取ることが可能です。

 

まとめ

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

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

 

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

 

そのため、Javaでちょっと凝ったことをするとよくロックしてしまっていたのですが、C#は実行時にわかりやすくエラーが出る上に、

Invoke(new delegate())

をすれば、そのスレッドで動かすことが可能です。

 

プログラミングの無料レッスン体験

 

約8,000名の受講生と80社以上の導入実績のあるプログラミングやWebデザインのオンラインマンツーマンレッスンCodecamp

<Codecampの特徴>

1 現役エンジニアによる指導

2オンラインでのマンツーマン形式の講義

3大手企業にも導入されている実践的なカリキュラム

↓無料体験レッスン実施中です。

プログラミングのオンラインスクールCodeCamp

 

 

コメント