C#のプログラムを作ってて
忘れるといけないのでまとめ
間違ってたり,補足があったらコメントしていただけると助かります.
あるメソッドAから別のあるメソッドBを呼び出そうとすると
エラーが出る場合がある
例:
private void serialPort1_DataReceived(略)
{
textBox1.text = "hoge";
}
みたいな感じにすると止まる.
やろうとしてたのはシリアルポートでなにかを受信したら
"hoge"をテキストボックスに表示するというアプリケーションの作成
やれない理由は,メソッドAが動いてるスレッド中にメソッドBを無理やり動かそうとするため
Windowsフォーム上でフォームを作成した場合,そのフォーム自身以外からのアクセスは動作が保障されていないため
まぁ,CheckForIllegalCrossThreadCalls プロパティの値を false に設定すれば動くようにはなるらしい.
が,根本的な解決になっていないのでいろいろ勉強した
使用したのはInvokeとdelegate
で,まぁ
Invokeっていうのは,別スレッドからコントロールを呼び出したときに
そのコントロールの操作を対象のスレッドで実行できるようにするメソッドで
System.Windows.formsに用意されている
delegateは
処理をしたいメソッドを直接書くのではなく,
その引数の型に合ったメソッドに処理の中継をしてくれるやつ
んで,この二つを使ってさっきのやつを書きなおすと
private void serialPort1_DataReceived(略)
{
setText("hoge");
}
delegate void myText(string text);
private void setText(string text)
{
if (this.textBox1.InvokeRequired)
{
myText d = new myText(setText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
っつう風になります.
んで,
if (this.textBox1.InvokeRequired) は
InvokeRequiredはInvokeが必要かどうかの判定
もっと言うと,同一のスレッドではない場合の処理
myText d = new myText(setText);
this.Invoke(d, new object[] { text });
は,delegateで宣言した myTextクラスのメソッドを宣言して
Invokeしてる
this.Invoke(d, new object[] { text });
{}内は,delegateで宣言した引数.
で,こんな感じにすれば
setText()は,どこでも動くものになりましたよって感じ
1 件のコメント:
just stopping by to say hello
コメントを投稿