2012-03-22 8 views
1

私のメインフォームForm1は、私のプログラムの主な部分を実行しています。C#テキストボックスの値を設定する元のスレッドに戻る

私はアルゴリズムを実行するために別のスレッドを開始しました。

私は新しいスレッド、方法MyAlgorithm()からメソッドを実行すると、私はメッセージとエラー

InvalidOperationExceptionが取得「それが作成されたスレッド以外のスレッドからアクセスコントロール名をコントロール。」

元のスレッドに戻って、最新の値でテキストボックスを更新する方法を実行するにはどうすればよいですか?

これは、アプリケーションのメインクラスであるForm1に含まれている、実行するメソッドです。

// Reset the results values 
public void ShowResults() 
{ 
    while (true) 
    { 

     loopsNum.Text = Convert.ToString(resultLoopsNum); 
     nodesVisitedNum.Text = Convert.ToString(resultNodesVisitedNum); 
     nodesResolvedNum.Text = Convert.ToString(resultNodesResolvedNum); 
     cpuLoopsNum.Text = Convert.ToString(resultCpuLoopsNum); 
     shortestPathCostNum.Text = Convert.ToString(resultShortestPathCost); 

    } 
} 

私は、Invoke()メソッドを見てきましたが、私は、ねじの方法から私のForm1の元のインスタンスを取得する方法がわかりません。私はこのように私のスレッドを起動してい

...

 // Set the algorithm method up in it's own thread 
     Thread thread = new Thread(new ThreadStart(MyAlgorithm)); 

     // Run the algorithm 
     thread.Start(); 
+0

[クロススレッド操作が有効でない:作成されたスレッド以外のスレッドからアクセスされたコントロール](http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid) -control-accessible-from-the-thread-other-than-the) –

答えて

2

Control.Invoke()を見てください:その他のオプションはここにも

public void ShowResults() 
{ 
    while (true) 
    { 
    Thread.Sleep(1000); // don't spam the UI thread 

    if (this.InvokeRequired) 
    { 
     this.Invoke((Action)UpdateGui); 
    } 
    else 
    { 
     UpdateGui(); 
    } 
    } 
} 

private void UpdateGui() 
{ 
    loopsNum.Text = Convert.ToString(resultLoopsNum); 
    nodesVisitedNum.Text = Convert.ToString(resultNodesVisitedNum); 
    nodesResolvedNum.Text = Convert.ToString(resultNodesResolvedNum); 
    cpuLoopsNum.Text = Convert.ToString(resultCpuLoopsNum); 
    shortestPathCostNum.Text = Convert.ToString(resultShortestPathCost); 
} 
+0

あなたのお手伝いをしていただきありがとうございます。しかし、私はなぜそれが 'アクション'オブジェクトである必要があるのか​​をよく理解していません。 Invokeでは、関数名だけでなくActionオブジェクトが必要なのはいつですか? – Luke

+1

これは、このメソッドを使用して、指定されたシグネチャを持つメソッドだけでなく、どのメソッドも呼び出すことができるからです。 [このオーバーロード](http://msdn.microsoft.com/en-us/library/a1hetckb.aspx)を参照してください。 – Gene

+0

さらに、[この質問では]良い説明があります(http://stackoverflow.com/questions/253138/anonymous-method-in-invoke-call)。 – Gene

1

あなたは使用することができます。

myform.Invoke(ShowResults); 
5

を私が実行できるように、私は元のスレッドに戻って取得するにはどうすればよいです最新の値でテキストボックスを更新する方法? Windowsフォームで

、あなたはどちらか使用Control.Invoke/BeginInvokeまたはBackgroundWorkerを使用して、progressイベントハンドラで更新を実行すると思います。

WPFでは、Dispatcher.Invoke/BeginInvokeを使用します。

C#5で

と.NET 4.5あなたは、はるかに簡単、このたくさんのをしなければならない非同期メソッドを使用することができます...私は呼び出し()メソッドを見てきました

が、 Form1の元のインスタンスをスレッドメソッドから取得する方法がわかりません。

「ねじ切り方法は、」Formの単なるインスタンスメソッドである場合は、すでにthis参照を持っています。そうでない場合は、別途「更新」部分を表すことができる場合は、Windowsフォームに直接依存しないように、理想的にはISynchronizeInvokeという情報を入力する必要があります。 (このインタフェースは、最近、同期コンテキストに有利になっているが、やはり完全にうまく機能する。)

1

あります:

代わりに、定期的にShowResultsを呼び出すためにSystem.Forms.Timerを使用しています。または、別のオプションを使用して操作を行うにはでなく、です。それをGUIスレッドで行い、GUIの更新を許可する場合は操作内からApplication.DoEvents()を呼び出してください。

最初のオプションは、間違ってGUIにInvokeリクエストを溢れさせないようにします.2番目のオプションはすべてGUIスレッド上にあり、状況が表示されるタイミングを細かく制御することができますGUI。

関連する問題