2009-08-23 13 views
1

スレッドからUIスレッドへデータをマーシャリングする方法については、stackoverflowを検索しています。Control.Invokeの間に単なる1つ以上のプロパティを設定する必要があります

私にとってより洗練されたソリューションの1つです。私はまだラムダを学んでいますが、閉鎖はこの解決策ですControl.Invoke with input Parametersです。

私はコードを完全に理解していませんが、私はそれを使用する方法を理解しており、私の問題は解決していません。

私はinvokeを呼び出して別のメソッド(DisplayStatusUpdate(msg))に文字列を渡したいと思います。任意のポインタが評価されるだろう。あなたが好きなように

private void FireEventAppender_OnMessageLogged(object sender, MessageLoggedEventArgs e) 
    { 
     DisplayStatusUpdate(e.LoggingEvent.RenderedMessage); 
    } 

    private void DisplayStatusUpdate(string text) 
    { 
     _StatusTextBox.Text = _StatusTextBox.Text + text; 
     _StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text); 
     _StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1; 
     _StatusTextBox.ScrollToCaret(); 
    } 

答えて

5

次の例のように、できるだけ多くのパラメータでこれを行うことができます。

private void FireEventAppender_OnMessageLogged(object sender, MessageLoggedEventArgs e) 
{ 
    DisplayStatusUpdate(e.LoggingEvent.RenderedMessage); 
} 

private delegate void DisplayStatusUpdateDelegate(string text); 

private void DisplayStatusUpdate(string text) 
{ 
    if(InvokeRequired) 
     this.Invoke(new DisplayStatusUpdateDelegate(DisplayStatusUpdate), text); 
    else 
    { 
     _StatusTextBox.Text = _StatusTextBox.Text + text; 
     _StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text); 
     _StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1; 
     _StatusTextBox.ScrollToCaret(); 
    } 
} 

私はかなりのコードを縮することができ、現在のプロジェクトで使用されている別の方法があります。詳細はhereです。 AOPの工場を使用してフォームを作成し

:あなたは、このメソッドを実装する場合

することは、あなたがする必要があるだろう

Form f = AOPFactory.Create<Form1>(); 
Application.Run(f); 

をそしてあなただけの[RunInUIThread]属性を持つイベントハンドラを飾ります。必要に応じて城のメソッド傍受モデルを使用して自動的に呼び出します。

したがって、上記のコードは次のようになります。

private void FireEventAppender_OnMessageLogged(object sender, MessageLoggedEventArgs e) 
{ 
    _StatusTextBox.Text = _StatusTextBox.Text + text; 
    _StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text); 
    _StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1; 
    _StatusTextBox.ScrollToCaret(); 
} 

パフォーマンスが賢明少し遅く、比較可能のようですが、あなたはそれがOKかもしれ何をしているかに応じて、それは間違いなく少ないコードになります。

+0

ニース、ありがとうブランドン。 SignatureがDisplayStatusUpdateのビットを少し変えようとしていたが、それを釘付けできないことが分かっていた。 –

+0

申し訳ありませんが、署名は同じですが、あなたが私の意図を知っていました。 –

2

あなたがC#3.5(またはそれ以降)を使用している場合は、コードを簡略化することが捕獲変数、使用することができます。コンパイラはここに舞台裏で何をするか

private void DisplayStatusUpdate(string text) 
{ 
    this.Invoke(new MethodInvoker(() => 
    { 
     _StatusTextBox.Text = _StatusTextBox.Text + text; 
     _StatusTextBox.Text = String.Format("{0}\r\n", _StatusTextBox.Text); 
     _StatusTextBox.SelectionStart = _StatusTextBox.Text.Length - 1; 
     _StatusTextBox.ScrollToCaret(); 
    })); 
} 

を保持するクラスを生成することですテキスト、MethodInvokerデリゲートを作成し、そのデリゲートと生成されたクラスのインスタンスをInvokeメソッドに渡します。上記の設計では、デリゲートを作成し、コードがすでに同じスレッドで実行されていてもInvokeを呼び出すという不必要な作業はもちろん行います。このような方法はパフォーマンス上の問題であると頻繁には呼ばれるべきではないと私は信じています。

MethodInvokerの使用を、パラメータなしのActionデリゲートまたはvoidを返すパラメータなしのデリゲートに置き換えることができます。

+0

それは素晴らしいです! – Brandon

関連する問題