2011-07-07 11 views
2

スレッドが2つあります。 私のワーカースレッド(メインスレッドではない)でピクチャボックス配列を作成し、メインフォームに新しいピクチャボックスを追加する必要がある場合もありますが、このフォームにはアクセスできません。私はどこかでinvokeメソッドを使う必要があると読んでいますが、私は1つのピクチャボックスやラベルを更新する方法しか知りません。 私はこのコードのビットでこれを行う方法がわからない:スレッドの問題C#

food[x].Location = new Point(100,100); 
food[x].Size = new Size(10,10); 
food[x].BorderStyle = BorderStyle.Fixed3D; 
food[x].ImageLocation = "food.png"; 
this.Controls.Add(food[x]); 
food[x].BringToFront; 

誰も私を助けてもらえますか?

+2

おそらく、複数のスレッドを持つべきではありません。 – SLaks

+4

SLaksが正しいです。これは起こるのを待っている災害のように聞こえる。 2つのスレッドが同じUI要素にアクセスしようとしているときに、UIプログラミングを正しく取得することは非常に困難です。通常、これは* UIスレッドのみがUI要素*と通信することが許可されている方法です。ワーカースレッドがUIと対話する必要がある場合は、ワーカースレッドがUIスレッドと通信するための何らかの方法を設定してから、UIスレッドがメッセージをUIオブジェクトに渡します。 –

+0

あなたはコード例やチュートリアルを習得していますか? – Dennis

答えて

2

WinFormsでは、1つのUIスレッドしか持たず、そのスレッドだけがUIコンポーネントを作成または使用する必要があります。

BackgroundWorkerを使用して画像を読み込み、PictureBoxの作成をBackgroundWorkerの完了時にUIスレッドに残しておきます。

1

バックグラウンドスレッドは、メインスレッドが所有するGUIコントロールにアクセスできません。

GUIに情報を伝えたい場合、スレッドはメインスレッドと通信しなければならず、GUI制御を操作しなければなりません。

BackgroundWorkerスレッドは、メインスレッドに信号を送る方法を提供します。たとえば、http://www.dotnetperls.com/backgroundworkerを参照してください。

0

WPFを使用する場合、SynchronazationContextを使用してメインスレッドを保存することをお勧めします。他のすべてのスレッドは、このSynchronazationContextのインスタンスを使用してメインスレッド(UI)にアクセスします。あなたは(:私はこれを行う方法を生成し、他のすべてのメソッドは、UIを更新するには、このメソッドにアクセスします注意してください):この方法でそれを使用

SynchronazationContext ctx = null; 
void DoSomething() 
{ 
    ctx = SynchronazationContext.Current; 
    Thread t = new Thread(new ThreadStart(ThreadProc)); 
    t.Start(); 
} 

//This method run in separate Threads 
void ThreadProc() 
{ 
    //Some algorithm here 

    SendOrPostCallback callBack = new SendOrPostCallback(UpdatePic); 
    ctx.Post(callBack, String.Format("Put here the pic path"); 
} 
void UpdatePic(string _text) 
{ 
    //This method run under the main method 
    //In this method you should update the pic 
} 

.NET 5.0では、あなたがマークインクルードすることで、この複雑な機能を呼び出すことができます同期メソッドを非同期メソッドとして作成し、メインスレッドでUIを更新する、同期メソッドを呼び出すと、非同期メソッドと書き込み 'await'メソッドを呼び出します。

+0

このコードをコピーして、私のコードを追加してupdatepixメソッドの画像ボックスを追加してください。また、スレッドprocメソッドにパス(food.png)を入れますか? 私は明日試してみますここでは3am;) – Dennis

+0

これはまさにあなたがやるべきことなのです。このようにして、他のスレッドからメインスレッドにアクセスします。私のサンプルコードにバグがありますが、すぐに修正します。私はDoSomethingメソッドからUpdatePicメソッドを呼び出しました。バグなしで今実行しようとしました。(私はそれを消しました) – Jacob

+0

これで私は問題があります。エラーメッセージが出ました。拡張メソッドは静的クラスにはありません。 ごめんなさい私 ドイツ語のerorrsだけを取得する私はあなたが私の意味を知って願っています。 これは問題です。 さらに、あなたは "ctx.Post(callBack、String.Format("ここにピクチャパスを入れてください) ";)を忘れました; – Dennis