2014-12-15 17 views
7

Ho un servizio Windows .Net (client) che comunica con un Hub SignalR (server). La maggior parte dei metodi client richiederà del tempo per essere completata. Quando si riceve una chiamata dal server, come faccio a (o devo) avvolgere il metodo/hub di destinazione. Per evitare l'avviso:Come utilizzare async/await con hub.On in Client SignalR

"Perché questa chiamata non è attesa, esecuzione del metodo corrente . continua prima che la chiamata è stata completata in considerazione l'applicazione l'operatore vi aspettano per il risultato della chiamata"

sul client, questo è un esempio del codice di avvio/installazione:

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

anche su il client, questo è un esempio dei metodi:

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

In definitiva, penso che _hub.On stia registrando il callback, non l'effettiva esecuzione (richiamo) dal server. Penso di aver bisogno di ottenere nel bel mezzo dell'esecuzione effettiva, attendere il risultato di On [X] FromServer e restituire il risultato.

************* esempio aggiornato con il codice corretto *********************

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

e poi la firma del metodo bersaglio sarebbe qualcosa di simile

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

Grazie a @AgentFire per la rapida risposta !!!

+2

Si raccomanda di non usare '.Wait();' 'ma attendono connection.start()', invece. – AgentFire

+0

Grazie per il suggerimento ... Ho aggiornato il codice per riflettere per i futuri lettori. –

risposta

6

Questo è un modello vuoto-awaitable, usarlo in questo modo:

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

Grazie per la risposta !!! Da una prospettiva di leggibilità, il "vuoto-attendibile" che restituisce un bool? Dal codice, non sembra che restituisca qualcosa. C'è un modo migliore per registrare il callback che potrebbe essere più chiaro agli altri sviluppatori che guardano il mio codice? O questo è abbondantemente chiaro agli sviluppatori reali e non è chiaro ad un principiante come me? :-) –

+2

Sì, il metodo async-void è abbastanza noto per tutti. Esistono tre tipi di metodo asincrono e ... dovresti conoscere l'intera faccenda, in realtà. Non ti farà male:] – AgentFire

+1

La tua risposta è l'unica risorsa su Internet per il termine * vuoto-attendente *. Inoltre non capisco che * vuoto asincrono * abbia a che fare con questo, oltre a * vuoto asincrono * altamente scoraggiato. – Stijn

Problemi correlati