0

C# を使用して Winforms で作業すると、別のスレッドで 2 番目の UI フォームを作成するメイン フォームがあります。

viewThread = new Thread( ( ) => 
{ 
  views = new Views.Views( displayRotators, screenLocationLeft, screenLocationTop, screenHeight, screenWidth );
  Application.Run( views );
} );
viewThread.SetApartmentState( ApartmentState.STA );
viewThread.Start( );

2 番目の UI フォームでは、メソッドを呼び出して、スレッドを終了するまで実行される表示ループを開始する必要があります。これを行う方法を見つけるのに約 3 時間を費やしましたが、見つけることができるのは、メイン UI スレッドからワーカー スレッドのメソッドを呼び出すのではなく、ワーカー スレッドからメイン UI スレッドのメソッドを呼び出す例だけです。どうすればこれを行うことができるか教えてもらえますか?

ありがとう。

4

2 に答える 2

3

複数の UI スレッドを実行することが本当に理にかなっているケースはほとんどありません。やむを得ない理由がない限り、単一の UI スレッドに戻ります。

複数の UI スレッドが必要であると仮定すると、ゴールデン ルールは、コントロールが作成された UI スレッドからのみコントロールを更新できるということです。. 一般にメソッドを呼び出したい場合は、それらをマーシャリングする必要はまったくありません。ただし、これらのメソッドが UI コントロールとやり取りする場合は、呼び出しがコントロールに属する UI スレッドではない他のスレッドからのものである場合とまったく同じ方法で、その呼び出しをマーシャリングします。

次のようなものがある場合

btnOnForm1OnUIThread1_Click(...)
{
    UpdateForm2OnUIThread2();
}

UpdateForm2OnUIThread2()
{
    if (control.InvokeRequired)
    {
      // Syntax of this line may be slightly off as I'm writing from memory ... 
      // I normally use an extension method
      control.Invoke(UpdateForm2OnUIThread2); 
    }
    else
    {
      control.Text = "Blah";
    }    
}
于 2013-01-28T21:03:21.650 に答える
0

を。何をすべきか分かっていれば、複数の UI スレッドを使用しても問題はありません。

b. UI スレッド ワーカーの呼び出しは正しくなく、混乱を招きます。開発者の観点からすると、UI スレッド #2 は #1 と同じです。気づけば、多くの問題は自ずと解決していきます。

c. view2.SomeMethod() [UI スレッド #2 で実行] を view1 [UI スレッド #1 で実行] から呼び出したい場合は、view2 で BeginInvoke を呼び出します。

以下のコードは簡単に採用できます。button1 - 2 番目の UI スレッドを起動します。button2 - UI スレッド 2 にあるフォームの UI スレッド 1 からメソッドを呼び出します

    Form2 form;
    private void button1_Click(object sender, EventArgs e)
    {
        Thread viewThread = new Thread(() =>
        {
            form = new Form2();
            Application.Run(form);
        });
        viewThread.SetApartmentState(ApartmentState.STA);
        viewThread.Start();

        label1.Text = Thread.CurrentThread.ManagedThreadId.ToString();

    }

    private void button2_Click(object sender, EventArgs e)
    {
        if (form != null)
        {
            form.BeginInvoke(new Action(() => 
                {form.Method("Form1 is calling...");}));
        }
    }

フォーム 2 :

    public void Method(string s)
    {
        label1.Text = string.Format("{0} '{1}'", 
                        Thread.CurrentThread.ManagedThreadId, s);
    }

スレッド番号が異なっていることがわかりますが、ストリングはそれらを交差しています。

于 2013-01-31T03:55:06.570 に答える