- PR -

別スレッドからコントロールにアクセス

1
投稿者投稿内容
ナリエモン
会議室デビュー日: 2004/03/25
投稿数: 7
投稿日時: 2004-03-25 00:48
お世話になっています。ナリエモンといいます。
スレッドの使い方を勉強しています。
System.Windows.Forms.Controlのコントロールは作成されたスレッドからでないと
メンバにアクセスし、読み書きができないと聞いたので実験してみました。

FormにTextBoxを一つ配置してFormのコンストラクタで
public Form1()
{
 InitializeComponent();
 thread_ = new Thread(new ThreadStart(Infinity));
 thread_.Start();
}
private void Infinity()
{
 while(true) textBox1.Text = "HaHaHa";
}
とスレッドを作成し実行するとTextBoxはずーとHaHaHaと表示されています。
つまり、textBox1は作成されたスレッド以外のスレッドからプロパティを
変更されていることになります。

よって
System.Windows.Forms.Controlのコントロールは作成されたスレッドからでないと
メンバにアクセスし、読み書きができないというのは間違いかな?
と思っています。

どうなんのでしょうか?
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-03-25 03:00
引用:

ナリエモンさんの書き込み (2004-03-25 00:48) より:
System.Windows.Forms.Controlのコントロールは作成されたスレッドからでないと
メンバにアクセスし、読み書きができないというのは間違いかな?
と思っています。


私はWindowsのUIに関するスレッドの制限やしくみなどの詳細は知りませんが、大抵の場合スレッド関連での制限と言う物は、「正常に動作する事もあるけれど、場合によってあるいはタイミングによって失敗する可能性がある」と言う物です。
# もちろん最初から全く動作しないタイプの制限だってあるでしょうけれど

また、例えばプロパティの読み書きが一見正常に出来ているように見えても、内部的に全ての動作が正しく行われたかは分かりません。

結局のところ、物によっては正しく動作する事もあるのかもしれないし、物によっては全く駄目かもしれない、でも全体として、少なくとも正しく動作する事は保証されないと言うことだと思います。
# 実際にうまく動かない例も出ています。

こういった制限事項と言うのは、必ず失敗する、もしくは必ずうまくいかないとは限らず、「必ず成功するとは限らない」ために「駄目」という仕様であることも多いと思った方が良いでしょう。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-03-25 09:13
 シンクロナイズすれば、他のスレッドからでも書き換えができます。が、シンクロナイズしなければ、どうなるかわかりません。

 ここでスレッドは1つですが、もう1つ同じようなスレッドを作り、それで「ehehe」と変更するようにしましょう。また、TextBoxですから、ユーザ入力も可能ですね。ユーザ入力も行いましょう。さてコントロールは、3つのスレッドからの変更要求の、どれに答えればいいのでしょう?

 .NETでは「シンクロナイズ(sync)」ではなく、「インボーク(invoke)」だったかも…っと、invokeでした。System.Windows.Forms.ControlクラスのInvokeメソッドの説明を読んでください。
引用:

メモ スレッドから安全に呼び出される 4 つのメソッド、 Invoke 、 BeginInvoke 、 EndInvoke 、および CreateGraphics がコントロール上にあります。その他のすべてのメソッドの呼び出しについては、Invoke メソッドの 1 つを使用して、その呼び出しをコントロールのスレッドにマーシャリングする必要があります。




 あっと、『読み書きができないと聞いた』この、「聞いた」というのが気になったのですが、それはあなたがMSDNなどを見て理解したのではなく、他の誰かがそういっていた、ということですよね。実験するのもいいですが、まず、マニュアルを確認しましょう。
 私の理解では、「読むことはできるが、書き込みはメインスレッドに同調しなければならない」です。←これもSunWindowで得た知識だなぁ…
1

スキルアップ/キャリアアップ(JOB@IT)