2009-08-23 9 views
1

Ich habe Stackoverflow für Möglichkeiten zum Marshalm Daten zurück von einem Thread zum UI-Thread gesucht, und habe verschiedene Möglichkeiten gefunden, es in 3.5 zu tun.Benötigen Sie mehr als nur eine einzige Eigenschaft während Control.Invoke

Eine der eleganteren Lösungen für mich; obwohl ich noch lambdas und verschlüsse lerne ist diese lösung Control.Invoke with input Parameters.

Ich verstehe den Code nicht vollständig, aber ich verstehe, wie man es benutzt, und es löst mein Problem nicht ganz.

Ich möchte aufrufen aufrufen und übergeben Sie eine Zeichenfolge an eine andere Methode (DisplayStatusUpdate (msg)). Alle Hinweise würden geschätzt werden.

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(); 
    } 

Antwort

5

Sie können dies tun, mit so vielen Parametern ab, wie Sie möchten, zum Beispiel:

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(); 
    } 
} 

Es gibt eine andere Methode, die ich habe in einem aktuellen Projekt verwenden, das den Code erheblich reduct kann. Details sind here.

Wenn Sie diese Methode implementieren, würden Sie müssen:

das Formular Erstellen Sie das AOP Fabrik mit:

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

Und dann dekorieren Sie einfach den Event-Handler mit dem [RunInUIThread] Attribut. Es verwendet das Methodenüberwachungsmodell von Castle, um bei Bedarf automatisch aufzurufen.

Somit wird der obige Code wird:

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(); 
} 

Performance weise scheint es vergleichbar, etwas langsamer zu sein, aber je nachdem, was Sie tun es in Ordnung sein kann, dauert es auf jeden Fall weniger Code.

+0

Schön, danke Brandon. Ich wusste, dass die Signatur sich für DisplayStatusUpdate ein wenig ändern würde, aber ich konnte es einfach nicht finden. –

+0

Entschuldigung, die Unterschrift ist die gleiche, aber Sie wussten, was ich meinte. –

2

Wenn Sie mit C# 3.5 (oder höher) Sie können erfasst Variablen verwenden, die den Code vereinfachen kann:

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(); 
    })); 
} 

Was der Compiler hinter den Kulissen tun hier ist eine Klasse zu erzeugen, um die halten Erstellen Sie einen MethodInvoker Delegaten und übergeben Sie diesen Delegaten und eine Instanz der generierten Klasse an die Invoke-Methode. In dem obigen Entwurf wird dies natürlich die unnötige Arbeit des Erstellens eines Delegaten und des Aufrufs von Invoke selbst dann ausführen, wenn der Code bereits auf demselben Thread läuft; Aber ich glaube, dass eine Methode wie diese nicht so oft als Performance-Problem bezeichnet werden sollte.

Wenn Sie möchten, können Sie die Verwendung von MethodInvoker durch den parameterlosen Action Delegaten oder einen anderen parameterlosen Delegaten ersetzen, der void zurückgibt.

+0

Das ist großartig! – Brandon

Verwandte Themen