[解決済み】クロススレッド操作が有効でない。作成されたスレッド以外のスレッドからアクセスされたコントロール
質問事項
あるシナリオがあります。(Windows Forms, C#, .NET)
- あるユーザーコントロールをホストするメインフォームがあります。
-
このユーザーコントロールは重いデータ操作を行うので、もし私が直接
UserControl_Load
メソッドを実行する間、UI は無応答になります。 - これを克服するために、私は別のスレッドでデータをロードします(できるだけ既存のコードを変更しないようにしています)。
- 私はバックグラウンドワーカスレッドを使いました。このスレッドはデータの読み込みを行い、完了したらアプリケーションにその作業を完了したことを通知します。
- さて、ここからが本当の問題です。すべてのUI(メインフォームとその子ユーザーコントロール)は、プライマリメインスレッドで作成されました。usercontrolのLOADメソッドでは、userControl上のいくつかのコントロール(テキストボックスなど)の値に基づいてデータを取得しています。
疑似コードは次のようになります。
コード1
UserContrl1_LoadDataMethod()
{
if (textbox1.text == "MyName") // This gives exception
{
//Load data corresponding to "MyName".
//Populate a globale variable List<string> which will be binded to grid at some later stage.
}
}
Exceptionは
クロススレッド操作が有効ではありません。作成されたスレッド以外のスレッドからコントロールにアクセスした。
このことについてもっと知るために、私はグーグルで検索し、次のコードを使用するような提案を得ました。
コード 2
UserContrl1_LoadDataMethod()
{
if (InvokeRequired) // Line #1
{
this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod));
return;
}
if (textbox1.text == "MyName") // Now it wont give an exception
{
//Load data correspondin to "MyName"
//Populate a globale variable List<string> which will be binded to grid at some later stage
}
}
しかし、しかし、しかし・・・、どうやら振り出しに戻ったようだ。アプリケーションは再び 無応答になる。1行目のif条件の実行が原因のようです。ロードタスクは、私がスポーンした3番目のスレッドではなく、再び親スレッドによって行われます。
私の認識が正しいのか間違っているのかわかりません。私はスレッディングの初心者なのです。
また、Line#1 if ブロックの実行はどのように影響するのでしょうか。
状況は次のとおりです。 : コントロールの値に基づいて、グローバル変数にデータをロードしたい。子スレッドからコントロールの値を変更したくありません。子スレッドからは絶対にやらない。
つまり、対応するデータをデータベースから取得できるように、値にのみアクセスするのです。
どのように解決するのですか?
の通りです。 Prerak Kの更新コメント (削除済み)。
<ブロッククオート質問の仕方が悪かったようです。
状況はこうです。コントロールの値に基づいて、グローバル変数にデータをロードしたい。子スレッドからコントロールの値を変更したくありません。子スレッドからは絶対にやらない。
つまり、対応するデータをデータベースから取得できるように、値にのみアクセスするのです。
そのとき、あなたが望む解決策は、次のようになるはずです。
UserContrl1_LOadDataMethod()
{
string name = "";
if(textbox1.InvokeRequired)
{
textbox1.Invoke(new MethodInvoker(delegate { name = textbox1.text; }));
}
if(name == "MyName")
{
// do whatever
}
}
本格的な処理は別スレッドで行う 以前 コントロールのスレッドに戻ろうとしたとき。例えば
UserContrl1_LOadDataMethod()
{
if(textbox1.text=="MyName") //<<======Now it wont give exception**
{
//Load data correspondin to "MyName"
//Populate a globale variable List<string> which will be
//bound to grid at some later stage
if(InvokeRequired)
{
// after we've done all the processing,
this.Invoke(new MethodInvoker(delegate {
// load the control with the appropriate data
}));
return;
}
}
}
関連
-
[解決済み】コレクションが変更され、列挙操作が実行されないことがある。
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】C#はJavaのcharAt()と同等?)
-
[解決済み】OnCollisionEnter2Dが実行されない?
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】Android "ビュー階層を作成した元のスレッドだけが、そのビューに触れることができる"
-
[解決済み] 他のスレッドからGUIを更新するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み】C#はJavaのcharAt()と同等?)
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み】MetadataException: 指定されたメタデータ・リソースをロードできない
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み】URLから画像をダウンロードする方法
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である
-
[解決済み】クロススレッド操作が有効でない。コントロール 'textBox1' が作成されたスレッド以外のスレッドからアクセスされた [duplicate] 。