2011-09-30 3 views
8

私はスレッドを練習していて、この問題を遭遇しました。私が制御する必要が別のスレッドからフォームのコントロールにアクセスする

  1. 私は単一のフォーム上の4つのプログレス・バー、ファイルをダウンロードするための1、ページの読み込み状況などを示すための1つを持っている...

  2. :状況はこのようなものです別のスレッドから各ProgressBarの進行状況を取得します。

問題は、私は、有効な

クロススレッド操作ではないと言うInvalidOperationExceptionがを取得していますされます。コントロール「progressBar1の」 それが作成されたスレッド以外のスレッドからアクセス。

私はこのアプローチで間違っていますか、誰かがこれを実装する方法を教えてもらえますか?

+1

Jon Skeetの[この](http://www.yoda.arachsys.com/csharp/threads/winforms.shtml)の記事をWindows Formsのスレッドでチェックしてください。物事をクリアするはずです。簡単な説明は、UIが独自のスレッドで動作するため、他のスレッドからUI要素を呼び出す必要があることです。 – alex

答えて

9

UI要素にアクセスできるのは、UIスレッドのみです。 WinFormsとWPF/Silverlightでは、複数のスレッドからコントロールにアクセスすることはできません。

A work-around to this limitation can be found here

2

フォームやその他のコントロールでいくつかのアクションを実行するには、非UIスレッドからメソッドを呼び出す必要があります。

+0

先進のプログラマーではありません。あなたはそれをどうやって行うのかアドバイスできますか?ありがとう –

+0

@ Chandu-Indyaah - 高度なプログラマーでなければ、BackgroundWorkerを使うべきです。 –

9

フラグControl.InvokeRequiredを確認し、必要に応じてControl.Invokeメソッドを使用できます。 Control.Invokeはデリゲートを受け取り、組み込みのアクション<T>を使用できるようにします。

public void UpdateProgress(int percentComplete) 
{ 
    if (!InvokeRequired) 
    { 
     ProgressBar.Value = percentComplete; 
    } 
    else 
    { 
     Invoke(new Action<int>(UpdateProgress), percentComplete); 
    } 
} 
30

Controlは、それを作成したスレッド(UIスレッド)内でのみアクセスできます。 UIスレッド上で、

Invoke(new Action(() => 
{ 
    progressBar1.Value = newValue; 
})); 

invokeメソッドはその後、与えられたデリゲートを実行します。

あなたのような何かをしなければならないでしょう。

+2

+1ラムダ関数を使用します。 – alex

5
private void Form1_Load(object sender, EventArgs e) 
    { 
     CheckForIllegalCrossThreadCalls = false; 
    } 

これはうまくいくかもしれません。

+0

このように推薦しませんが、それはうまく動作します:-) – Swanand

関連する問題