2009-05-15 18 views
4

Ich versuche, eine Erweiterungsmethode für die generischen Delegaten Action<T> in der Lage sein, um einfache asynchrone Aufrufe auf Action<T> Methoden zu erstellen. Es besteht im Wesentlichen implementiert nur das Muster, wenn Sie möchten, das Verfahren auszuführen und kümmern sich nicht um sie Fortschritt ist:Wie wird diese Erweiterungsmethode kompiliert?

public static class ActionExtensions 
{ 
    public static void AsyncInvoke<T>(this Action<T> action, T param) { 
     action.BeginInvoke(param, AsyncActionCallback, action); 
    } 

    private static void AsyncActionCallback<T>(IAsyncResult asyncResult) { 
     Action<T> action = (Action<T>)asyncResult.AsyncState; 
     action.EndInvoke(asyncResult); 
    } 
} 

Das Problem ist, dass es wegen der zusätzlichen <T> nicht kompiliert werden, die die AsyncActionCallback generic macht und habe eine andere Signatur als erwartet. Die Signatur void AsyncActionCallback(IAsyncResult) wird erwartet.

Wer weiß, wie dies zu umgehen oder accomlish, was ich tun möchte?

Antwort

7
public static void AsyncInvoke<T>(this Action<T> action, T param) 
{ 
    action.BeginInvoke(param, asyncResult => 
    { 
     Action<T> a = (Action<T>)asyncResult.AsyncState; 
     a.EndInvoke(asyncResult); 
    }, action); 
} 
+0

Das ist ein Weg :) Gutes Denken. – leppie

+0

Super, vielen Dank für die blitzschnelle Antwort! Es ist interessant, wie Lambdas etwas ermöglichen, was vorher nicht möglich war. Ich denke, es ist schließlich nicht nur Zucker! –

+0

Beachten Sie, dass dieser Ansatz dazu führen kann, dass Fehler, die während des Aufrufs auftreten, auf dem Boden gelöscht werden. Möglicherweise möchten Sie den Inhalt des Lambda innerhalb eines try {} catch {} umbrechen. –

0

AsyncActionCallback<T>?

Haftungsausschluss: nicht sicher über die oben könnte eine jener ‚Grenzen‘ sein.

+0

Ich bin nicht sicher, was du meinst. Ich verwende genau die gleiche Signatur in dem Code, den ich gepostet habe. Aber auch das würde nicht kompilieren, da der Compiler den Typparameter nicht erwartet. Wie auch immer, Darins Lösung, die eine Lamda anstelle des Delegaten verwendet, funktioniert. –

0

Wenn Sie Ihre Funktion getrennt halten wollen (nicht als Lambda) was ist so etwas wie dieses:

public static void AsyncInvoke<T>(Action<T> action, T param) 
{ 
    action.BeginInvoke(param, new AsyncCallback(AsyncActionCallback<T>), action); 
} 
Verwandte Themen