Da Invoke/ BeginInvokeakzeptiert Delegate(anstelle eines typisierten Delegaten), müssen Sie dem Compiler mitteilen, welcher Delegatentyp erstellt werden soll. MethodInvoker(2.0) oder Action(3.5) sind gängige Optionen (beachten Sie, dass sie dieselbe Signatur haben). wie so:
(Einschränkung: Sie müssen etwas vorsichtig sein, wenn Sie asynchrone Captures verwenden , aber die Synchronisierung ist in Ordnung - dh die oben genannten sind in Ordnung.)
Eine andere Möglichkeit besteht darin, eine Erweiterungsmethode zu schreiben:
Wie kann ich in dieser Antwort Parameter an Ihre erste Lösung übergeben? Ich meinte diese Lösung: control.Invoke ((MethodInvoker) delegate {this.Text = "Hi";});
uzay95
1
Warum wird die Erweiterungsmethode aufgerufen, ohne dass eine explizite Umwandlung in eine Aktion durchgeführt werden muss?
P.Brian.Mackey
Weil der Compiler das aus der Verwendung ableiten kann.
RoboJ1M
1
Es ist das gleiche wie in der Lage zu sein, Form.Load += Loader()anstelle des altenForm.Load += new EventHandler(Loader())
RoboJ1M
49
Eigentlich müssen Sie kein delegate-Schlüsselwort verwenden. Übergeben Sie einfach Lambda als Parameter:
Sie müssen einen Delegatentyp erstellen. Das Schlüsselwort 'delegate' bei der Erstellung anonymer Methoden ist etwas irreführend. Sie erstellen keinen anonymen Delegaten, sondern eine anonyme Methode. Die von Ihnen erstellte Methode kann in einem Delegaten verwendet werden. So was:
Der Vollständigkeit halber kann dies auch über eine Kombination aus Aktionsmethode und anonymer Methode erfolgen:
//Process is a method, invoked as a method groupDispatcher.Current.BeginInvoke((Action)Process);//or use an anonymous methodDispatcher.Current.BeginInvoke((Action)delegate=>{SomeFunc();SomeOtherFunc();});
Invoke((Action) Process);ist die beste Antwort, danke!
Jinjinov
5
Ich hatte Probleme mit den anderen Vorschlägen, weil ich manchmal Werte von meinen Methoden zurückgeben möchte. Wenn Sie versuchen, MethodInvoker mit Rückgabewerten zu verwenden, scheint es Ihnen nicht zu gefallen. Die Lösung, die ich verwende, ist also wie folgt (sehr erfreut zu hören, wie man dies prägnanter macht - ich verwende c # .net 2.0):
// Create delegates for the different return types needed.privatedelegatevoidVoidDelegate();privatedelegateBooleanReturnBooleanDelegate();privatedelegateHashtableReturnHashtableDelegate();// Now use the delegates and the delegate() keyword to create // an anonymous method as required// Here a case where there's no value returned:publicvoidSetTitle(string title){
myWindow.Invoke(newVoidDelegate(delegate(){
myWindow.Text= title;}));}// Here's an example of a value being returnedpublicHashtableCurrentlyLoadedDocs(){return(Hashtable)myWindow.Invoke(newReturnHashtableDelegate(delegate(){return myWindow.CurrentlyLoadedDocs;}));}
// Thread-safe update on a form controlpublicvoidDisplayResult(string text){if(txtResult.InvokeRequired){
txtResult.Invoke((Action)delegate{DisplayResult(text);});return;}
txtResult.Text+= text +"\r\n";}
Bonus: Fügen Sie eine Fehlerbehandlung hinzu, da es wahrscheinlich ist, dass Sie bei Verwendung Control.Invokeeines Hintergrundthreads den Text- / Fortschritts- / Aktivierungsstatus eines Steuerelements aktualisieren und es egal ist, ob das Steuerelement bereits entsorgt ist.
Form.Load += Loader()
anstelle des altenForm.Load += new EventHandler(Loader())
Eigentlich müssen Sie kein delegate-Schlüsselwort verwenden. Übergeben Sie einfach Lambda als Parameter:
quelle
quelle
Sie müssen einen Delegatentyp erstellen. Das Schlüsselwort 'delegate' bei der Erstellung anonymer Methoden ist etwas irreführend. Sie erstellen keinen anonymen Delegaten, sondern eine anonyme Methode. Die von Ihnen erstellte Methode kann in einem Delegaten verwendet werden. So was:
quelle
Der Vollständigkeit halber kann dies auch über eine Kombination aus Aktionsmethode und anonymer Methode erfolgen:
quelle
Invoke((Action) Process);
ist die beste Antwort, danke!Ich hatte Probleme mit den anderen Vorschlägen, weil ich manchmal Werte von meinen Methoden zurückgeben möchte. Wenn Sie versuchen, MethodInvoker mit Rückgabewerten zu verwenden, scheint es Ihnen nicht zu gefallen. Die Lösung, die ich verwende, ist also wie folgt (sehr erfreut zu hören, wie man dies prägnanter macht - ich verwende c # .net 2.0):
quelle
Ich verwende Action gerne anstelle von MethodInvoker, es ist kürzer und sieht sauberer aus.
Z.B.
quelle
Ich habe nie verstanden, warum dies für den Compiler einen Unterschied macht, aber das ist ausreichend.
Bonus: Fügen Sie eine Fehlerbehandlung hinzu, da es wahrscheinlich ist, dass Sie bei Verwendung
Control.Invoke
eines Hintergrundthreads den Text- / Fortschritts- / Aktivierungsstatus eines Steuerelements aktualisieren und es egal ist, ob das Steuerelement bereits entsorgt ist.quelle