2014-12-15 6 views
7

Ich habe einen .Net Windows-Dienst (Client), der mit einem SignalR Hub (Server) kommuniziert. Die meisten Clientmethoden benötigen Zeit. Beim Empfang eines Anrufs von dem Server, wie ich (oder muss ich), um die Zielmethode/hub.On wickeln um die Warnung zu vermeiden:Wie async/await mit hub.On im SignalR-Client verwenden

„Da dieser Anruf erwartete nicht, die Ausführung des aktuellen Verfahrens . weiter, bevor der Anruf beendet ist Betrachten Sie den await Operator auf das Ergebnis des Aufrufs“

auf der Client-Anwendung ist dies eine Probe des/Setup-Code starten:

IHubProxy _hub 
string hubUrl = @"http://localhost/"; 

var connection = new HubConnection(hubUrl, hubParams); 
_hub = connection.CreateHubProxy("MyHub"); 
await connection.Start(); 

_hub.On<Message>("SendMessageToClient", i => OnMessageFromServer(i.Id, i.Message)); 
_hub.On<Command>("SendCommandToClient", i => OnCommandFromServer(i.Id, i.Command)); 

auf auch der Client, dies ist ein Beispiel für die Methoden:

public static async Task<bool> OnMessageFromServer(string Id, string message) 
{ 
    try 
    { 
     var result = await processMessage(message); //long running task 
    } 
    catch (Exception ex) 
    { 
     throw new Exception("There was an error processing the message: ", ex); 
    } 
    return result; 
} 

public static async Task<bool> OnCommandFromServer(string Id, string command) 
{ 
    try 
    { 
     var result = await processCommand(command); //long running task 
    } 
    catch (Exception ex) 
    { 
     throw new Exception("There was an error processing the message: ", ex); 
    } 
    return result; 
} 

Letztendlich denke ich, die _hub.On den Rückruf registriert, nicht die tatsächliche Ausführung (aufrufen) vom Server. Ich denke, ich muss mitten in der eigentlichen Ausführung sein, auf das Ergebnis von On [X] FromServer warten und das Ergebnis zurückgeben.

************* aktualisiert Beispiel mit korrigierten Code *********************

IHubProxy _hub 
string hubUrl = @"http://localhost/"; 

var connection = new HubConnection(hubUrl, hubParams); 
_hub = connection.CreateHubProxy("MyHub"); 
await connection.Start(); 

//original 
//_hub.On<Message>("SendMessageToClient", i => OnMessageFromServer(i.Id, i.Message)); 
//_hub.On<Command>("SendCommandToClient", i => OnCommandFromServer(i.Id, i.Command)); 

//new async 
_hub.On<Message>("SendMessageToClient", 
    async (i) => await OnMessageFromServer(i.Id, i.Message)); 

_hub.On<Message>("SendCommandToClient", 
    async (i) => await OnCommandFromServer(i.Id, i.Message)); 

//expanding to multiple parameters 
_hub.On<Message, List<Message>, bool, int>("SendComplexParamsToClient", 
    async (p1, p2, p3, p4) => 
     await OnComplexParamsFromServer(p1.Id, p1.Message, p2, p3, p4));  

und dann wäre die Zielmethode Signatur etwas wie

public static async Task<bool> OnComplexParamsFromServer(string id, string message, 
       List<Message> incommingMessages, bool eatMessages, int repeat) 
{ 
    try 
    { 
     var result = await processCommand(message); //long running task 
     if (result) 
     { 
      // eat up your incoming parameters 
     } 
    } 
    catch (Exception ex) 
    { 
     throw new Exception("There was an error processing the message: ", ex); 
    } 
    return result; 
} 

Dank @AgentFire für die schnelle Antwort !!!

+2

Es wird empfohlen, nicht zu verwenden '.Wait();' 'aber erwarten connection.Start()' statt. – AgentFire

+0

Danke für den Tipp ... Ich habe den Code für zukünftige Leser aktualisiert. –

Antwort

6

Dies ist ein hohlraum awaitable Muster, es wie folgt verwendet werden:

_hub.On<Message>("SendMessageToClient", async i => await OnMessageFromServer(i.Id, i.Message)) 
+0

Danke für die Antwort !!! Aus einer Lesbarkeitsperspektive, die "Leere-Erwartete", die einen Bool zurückgibt? Aus dem Code sieht es nicht so aus, als würde es irgendetwas zurückgeben. Gibt es eine bessere Möglichkeit, den Rückruf zu registrieren, der für andere Entwickler, die meinen Code ansehen, klarer ist? Oder ist das für echte Entwickler klar und einfach nicht klar für einen Neuling wie mich? :-) –

+2

Ja, die async-void-Methode ist ziemlich bekannt für alle. Es gibt drei Arten von Async-Methode und ... Sie sollten eigentlich über die ganze Sache lernen. Wird dir nicht weh tun:] – AgentFire

+1

Deine Antwort ist die einzige Ressource im Internet für den Begriff * void-awaritable *. Ich verstehe auch nicht, was * async void * damit zu tun hat, zusätzlich zu * async void *, das stark davon abgehalten wird. – Stijn

Verwandte Themen