2012-01-18 8 views
0

私はウィンドウのフォームでマルチスレッドを使用していました。以下は私のクラスです。 私はデザイナーのラベルコントロールを持っていて、新しく作成されたスレッドの下で、テキストプロパティを更新しています。スレッドと匿名メソッドの代理人 - 新しいスレッドのコントロールを更新する

デリゲートの "Del"に "UpdateLabel"という関数をカプセル化したケースがあります。 と正常に動作します。

public partial class DynamicType : Form 
    { 
     delegate void Del(String x); 

     public DynamicType() 
     { 
      InitializeComponent(); 
     } 

     private void DynamicType_Load(object sender, EventArgs e) 
     { 
      System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(StartThread)); 
      t.Start(); 
     } 

     private void StartThread() 
     { 
      this.Invoke(new Del(UpdateLabel), new object[] { "Hi" }); 
     } 

     private void UpdateLabel(String str) 
     { 
      label1.Text = str; 
     } 
    } 

匿名メソッドと呼ばれる別のケースがあります。以下のメソッドで匿名メソッド を実装する際に。以下はその定義です。

private void StartThread() 
     { 
      UpdateLabel("Hi"); 
     } 



private void UpdateLabel(String str) 
     { 
      Del Label = delegate(String k) 
      { 
       label1.Text = k; 

      }; 
      Label("hi"); 
     } 

クロススレッド操作有効ではありません:それが作成されたスレッド以外のスレッドからアクセスコントロール「LABEL1」。

代理人を使用していた前のケースではクエリが実行されていましたが、正常に動作しました。匿名メソッドの場合は、代理人を直接インスタンス化して余分な関数を削除し、ラベルコントロールのテキストプロパティを更新しようとしました。上記のように。理由?

答えて

1

最初の例では、UIスレッドでラベル更新を呼び出しています(Form.Invoke経由)。これは正しく、動作します:

this.Invoke(new Del(UpdateLabel), new object[] { "Hi" }); 

2番目の例では、あなたがバックグラウンドスレッドにデリゲートを作成していると、バックグラウンドスレッドにそのデリゲートを開始します。これは、バックグラウンドスレッドがUIを更新するために許可されていないため、動作しません:

Del Label = delegate(String k) { label1.Text = k; }; 
Label("hi"); // runs in the same thread 

これを解決するには、UIスレッドでデリゲートを実行するためにthis.Invokeを使用しています

Del Label = delegate(String k) { label1.Text = k; }; 
this.Invoke(Label, new object[] {"hi"}); // runs in the UI thread 
関連する問題