.NET でマルチスレッドにしてlabelを変化させるには?

解決


POPO  2007-01-03 02:27:45  No: 64140

表題のことがどうしても出来ません。
ttp://dobon.net/vb/melma/dotnet25.txt
を参考にしてC++ようにしてみたつもりなのですが
エラーで"有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロールがアクセスされました。"
と出てしまいます。
どのようにしたらいいのでしょうか?
サンプルなどがあったら教えていただきたいです。
よろしくお願いいたします。


Blue  2007-01-03 09:47:03  No: 64141

どんなコードを書いていますか?

示されたサイトにも書いてありますが、InvokeRequired をしらべて
Invokeメソッドを呼ぶ必要があります。

参考
http://www.atmarkit.co.jp/fdotnet/dotnettips/312ctrlinvoke/ctrlinvoke.html

一応VB.NETでサンプルを書いたことはあるので参考になれば。
http://rararahp.cool.ne.jp/cgi-bin/lng/dotnet/dotnetlng.cgi?print+200611/06110002.txt


Blue  2007-01-03 10:30:19  No: 64142

ちなみに、VS2005ならば、Background Workerオブジェクトをつかうと
カナリ便利です。

参考(VB2005)
http://www.atmarkit.co.jp/fdotnet/vb2005/vb2005_04/vb2005_04_01.html


POPO  2007-01-03 11:58:56  No: 64143

>どんなコードを書いていますか?
一番初めに挙げた所のをC++にしただけです。
すみません実はいろいろ試したんですがReleaseでしたら動きました。
ただこれだと
private int AddString(string str)
{
    TextBox1.AppendText(str + "\r\n");
    return TextBox1.Lines.Length;
}
↑(VBですが)ひとつのラベルごと関数が必要になってしまいます。

ですのでBackground Workerのほうを試したのですが
private: System::Void button4_Click(System::Object^  sender, System::EventArgs^  e) {
this->backgroundWorker1->RunWorkerAsync();
     }
private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {

int i;
for(i=0;i<30;i++){
this->label1->Text=i.ToString();
this->label1->Update();
System::Threading::Thread::Sleep((1000));
}
これでlabel1は変わってくれません。


POPO  2007-01-03 12:45:50  No: 64144

そもそもこれをする必要があるのかもわからないので、
しようと思ってることを書きます。

データーとして構造体にint timeとint idとint dataを準備して
time時間経過後にidによってlabel1やlabel2を対象に
そのtextをdataに変えようと思ってます。
時間経過までの間でもボタン等の操作はしたいのでマルチスレッドについて
調べています。


Blue  2007-01-04 00:08:24  No: 64145

普通にタイマーコントロールを使うべきかと思います。


Blue  2007-01-04 00:13:10  No: 64146

ちなみに
>private: System::Void button4_Click(System::Object^  sender, System::EventArgs^  e) {
>this->backgroundWorker1->RunWorkerAsync();
> }
>private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {
>
>int i;
>for(i=0;i<30;i++){
>this->label1->Text=i.ToString();
>this->label1->Update();
>System::Threading::Thread::Sleep((1000));
>}
試しましたが、ちゃんと変わりますよ。


POPO  2007-01-04 01:14:38  No: 64147

>タイマーコントロールを使うべき

ありがとうございます調べてみます。

>試しましたが、ちゃんと変わりますよ。
うーん、私のほうでは動きません。

この頃、インテリセンスが使えなくなったりブレークポイントが
勝手に無効になったり、マウスポインターあてても宣言がみれないので
私のPCの問題ですね。再インストールもしてみます。
ありがとうございました。


Blue  2007-01-04 01:34:52  No: 64148

>うーん、私のほうでは動きません。
まっさらな状態(新規プロジェクト)から、そのコードだけ入れても
ダメでしょうか?

>インテリセンスが使えなくなったり
VS2005のインテリセンスって、なんか使いづらいですね。
PCの性能によるんでしょうが、私もなかなか出てこないときがあります。
ちょっと待つと(プロパティウィンドウを右に表示しているのですが、そこが正しく表示される?と)有効になるようです。


POPO  2007-01-04 02:46:09  No: 64149

>まっさらな状態(新規プロジェクト)から、そのコードだけ入れても
>ダメでしょうか?
まっさらで試して、初め動きませんでしたが
デバックなしだと動きました。

インテリセンスの件他の方もそうなんですね。

これで完成にまた一歩近づくことができました。
ありがとうございます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






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