2016-06-09 23 views
5

Sono un modo sostanziale attraverso lo sviluppo di una notevole applicazione WPF che controllerà un sofisticato hardware tramite comunicazioni seriali. In fondo all'applicazione "stack" ho un livello di comunicazione seriale (utilizzando la classe .Net "SerialPort"). Leggere e scrivere sul dispositivo h/w è una parte fondamentale del sistema, utilizzata da molte aree diverse del livello della logica aziendale, spesso intervallate da complessi calcoli scientifici e altre logiche simili; questi metodi BLL sono a loro volta chiamati da tutto il livello dell'interfaccia utente.Devo usare async "fino in fondo" per la mia app GUI?

Attualmente, tutto nel livello della logica aziendale, compresa la lettura e la scrittura SerialPort, è sincrono. L'unica volta che utilizzo async/await è nel livello UI, in genere quando si richiama la logica aziendale. Qui io avvolgere la chiamata in Task.Run(), e.g.:-

private async void SomeButtonClick(object sender, EventArgs e) 
{ 
    await Task.Run(() => _someBLLService.TurnPumpOn()); 
} 

Questo è un semplice esempio che prende una questione di millisecondi. Un esempio più complesso sarebbe l'avvio di un processo di lunga durata (sempre utilizzando la tecnica sopra); questo "servizio" di logica aziendale verrà eseguito per alcuni secondi o minuti, raccogliendo dati dall'hardware ed eseguendo altre funzioni di "controllo" durante questo periodo. Periodicamente trasmetterà i dati all'interfaccia utente per il tracciamento su un grafico (tramite un framework di aggregazione di eventi pubsub). La tecnica di cui sopra funziona bene, consentendo all'interfaccia utente di rimanere reattiva mentre si svolgono tali processi di livello aziendale.

Ho preso in considerazione l'idea di passare "asincrono completamente", iniziando dal codice di comunicazione seriale (ad esempio utilizzando .ReadAsync), ma ciò avrebbe ripercussioni su tutto il sistema. Decine (se non centinaia) di metodi di business logic dovrebbero essere rifattorizzati in metodi asincroni, fino al livello dell'interfaccia utente. Qui vorrei essere in grado di semplificare un po 'il codice di cui sopra:

private async void SomeButtonClick(object sender, EventArgs e) 
{ 
    await _someBLLService.TurnPumpOn(); 
} 

Mentre io non sono contrario a affrontare grandi lavori di refactoring, mi chiedo quali sono i benefici sono davvero. Un sacco di persone (come Stephen Cleary) sostengono la soluzione "async all the way", ma l'obiettivo principale sembra essere quello di mantenere l'interfaccia utente reattiva quando chiama un processo BLL di lunga durata, che già fa la mia tecnica Task.Run().

+2

Per chiarire, "async all the way" è un altro modo per dire "non bloccare il codice asincrono" - va solo in un modo.Nel caso di un'app dell'interfaccia utente, il principale vantaggio di async è la reattività e 'attendere Task.Run' è una soluzione perfetta se questo funziona per te. –

risposta

7

Poiché l'app (presumibilmente) non è soggetta a un carico elevato ed è un'app della GUI, l'unico motivo per utilizzare async e attendere è la produttività. Throughput e scalabilità non entrano nell'immagine.

Pertanto, fare ciò che è più conveniente per voi. Questo può benissimo essere il pattern await Task.Run che hai usato nel codice di esempio.

ma questo avrebbe ripercussioni in tutto il sistema

Sì. Async ha un notevole costo di produttività ed è contagioso. Fallo solo se riesci a esprimere chiaramente i benefici che ottieni da quella scelta. Qui, l'unico vantaggio è che il tuo codice UI è più corto di alcuni caratteri. È la differenza tra i due frammenti di codice. L'intero resto del sistema peggiora.

Forse hai seguito la community di C# e hai colto la tendenza per andare fino in fondo asincrono. I programmatori sono molto inclini a saltare a soluzioni magiche senza comprenderli. Molti sostenitori di async non riescono nemmeno ad articolare i benefici concreti che ne derivano. C'è anche un sacco di pensieri di gruppo. Non basare la tua decisione sui consigli di internet da solo. Fattene conto e verificate voi stessi cosa abbia senso.

+0

Ora è solo un'app desktop, ma ci sono piani per utilizzare SignalR per esporre alcuni metodi BLL, ad es. per un client smartphone per fornire un controllo limitato del dispositivo h/w (non più di uno o due client). La mia comprensione è che SignalR gestisce le connessioni client in modo asincrono, quindi presumibilmente non è ancora un buon motivo per asincronicamente? –

+0

SignalR supporta la restituzione di un'attività. Quel compito può essere semplicemente 'Task.FromResult' o qualsiasi altro modo per creare un'attività" fittizia ". Se non c'è carico non ci sono problemi di perf. SignalR servirà * internamente * utilizzando un socket socket efficiente e ne trarrai vantaggio. – usr

Problemi correlati