2010-12-15 16 views
4

Cの新機能ですので、私と一緒に裸です。メインスレッドのテキストボックスとラベルを、別のクラスを実行している新しいスレッドから更新する方法。メインスレッドのテキストボックスを別のスレッドから更新するには?

MainForm.cs(メインスレッド)

public partial class MainForm : Form 
{ 
    public MainForm() 
    { 
     Test t = new Test(); 

     Thread testThread = new Thread(new ThreadStart(t.HelloWorld)); 
     testThread.IsBackground = true; 
     testThread.Start(); 
    } 

    private void UpdateTextBox(string text) 
    { 
     textBox1.AppendText(text + "\r\n"); 
    } 

} 

public class Test 
{ 
    public void HelloWorld() 
    { 
     MainForm.UpdateTextBox("Hello World"); 
     // How do I execute this on the main thread ??? 
    } 
} 

私はここでの例を見てきましたが、それは権利を取得するように見える傾けます。誰かが良いリンクを張ってくれますか?

私はコードを壊さないように、私は再び新鮮に始めました。もし誰かが私の例を使って実例を立てたいなら、それはすばらしいでしょう。

また、テキストボックスやラベルなどの複数のオブジェクトを更新する必要があった場合(同時にすべてではない)、各テキストボックスのメソッドを持つか、これを行う方法があります一つの方法で?私が新しく言ったように、ゆっくり話してください。

+0

歓迎を使用することです:あなたは、ラムダ式にまで読むことができることに慣れて取得し、それが好きですか

public class MainForm : Form { public MainForm() { Test t = new Test(); Thread testThread = new Thread((ThreadStart)delegate { t.HelloWorld(this); }); testThread.IsBackground = true; testThread.Start(); } public void UpdateTextBox(string text) { Invoke((MethodInvoker)delegate { textBox1.AppendText(text + "\r\n"); }); } } public class Test { public void HelloWorld(MainForm form) { form.UpdateTextBox("Hello World"); } } 

そう。質問を編集して追加情報を追加することができます。また、あなたが質問した質問(および50人の担当者をヒットした後の質問)の回答にコメントを残すこともできます。 – Will

答えて

3

BeginInvoke methodを呼び出すと、UIスレッドでデリゲートを非同期に実行するようにキューに入れることができます。

UIスレッドで関数が終了するまでバックグラウンドスレッドが待機する必要がある場合は、代わりにInvokeを呼び出すことができます。

フォームのインスタンスへの参照が必要になります。おそらくそれをTestコンストラクタに渡してプライベートフィールドに格納する必要があります。


BackgroundWorker componentReportProgressメソッドを使用して自動的にこのすべてを行います。それを使用することを検討する必要があります。

+0

答えてくれてありがとうございます。しかし、C#の新機能です。 – tiptopjones

+1

@tiptop:おそらくBackgroundWorkerを使うべきです。 [MSDNには例があります](http://msdn.microsoft.com/en-us/library/waw3xexc.aspx) – SLaks

+0

すべてのWinForms開発者はスレッドセーフな方法でUIを更新する方法を理解する必要があり、どちらの方法も – STW

6

InvokeまたはBeginInvoke。

Invoke((MethodInvoker)delegate { 
    MainForm.UpdateTextBox("Hello World"); 
}); 

@tiptopjonesは、私は、フォームへの参照を取得する方法も求めていると思います。 HelloWorldメソッドにオブジェクトパラメータを渡し、ParameterizedThreadStartデリゲートを使用して、フォームへの参照をThread.Startメソッドのパラメータとして渡すことができます。しかし、匿名の方法について読むことをお勧めします。匿名の方法は、はるかに簡単になり、強く型付けされたものをすべて保持します。

Thread testThread = new Thread(() => t.HelloWorld(this)); 
+0

ちょっと、質問を編集して別の答えを提供するのではなく、情報を追加する方が望ましいです。 – Will

1

WinFormsの中れる好ましい方法はへのSynchronizationContextは

public partial class MainForm : Form 
{ 
    SynchronizationContext ctx; 

    public MainForm() 
    { 
     ctx = SynchronizationContext.Current; 

     Test t = new Test(); 

     Thread testThread = new Thread(new ThreadStart(t.HelloWorld)); 
     testThread.IsBackground = true; 
     testThread.Start(); 
    } 

    private void UpdateTextBox(string text) 
    { 
     ctx.Send(delegate(object state) 
     { 
      textBox1.AppendText(text + "\r\n"); 

     },null); 
    }  
} 

public class Test 
{ 
    public void HelloWorld() 
    { 
     MainForm.UpdateTextBox("Hello World"); 
     // How do I excute this on the main thread ??? 
    } 
} 
関連する問題