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

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

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

 

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

 

WS000011

 

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

 

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

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

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

 

WS000019

 

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

 

 

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

 

WS000020

 

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

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

 

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

 

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

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

 

 

WS000021

 

delegate void delegate1()

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

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

 

まとめ

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

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

 

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

 

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

Invoke(new delegate())

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

 

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

 

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

<Codecampの特徴>

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

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

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

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

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

 

 

コメント