Sto lavorando a una soluzione che utilizza lo streaming di memoria asincrono e sto pensando a un approccio corretto per l’implementazione di tale. Quale è più conveniente? Il primo, semplice:
//First approach: linear async private async static Task WriteToStreamFirstVariant() { MemoryStream memoryStream = new MemoryStream(); byte[] data = new byte[256]; try { await memoryStream.WriteAsync(data, 0, data.Length); } catch(Exception exception) { //Handling exception } finally { memoryStream.Dispose(); } }
O il secondo con attività e chiusure annidate?
//Second approach: nested tasks async private async static Task WriteToStreamSecondVariant() { await Task.Run(async () => { byte[] data = new byte[256]; using (MemoryStream memoryStream = new MemoryStream()) { await memoryStream.WriteAsync(data, 0, data.Length) .ContinueWith((Task writingTask) => { //Handling exceptions AggregateException exceptions = writingTask.Exception; }); } }); }
Il fatto è che i metodi Read/WriteAsync
MemoryStream
non forniscono alcun tipo di vera implementazione asincrona. Tutto ciò che fanno è eseguire l’operazione in modo sincrono e restituire un’attività già completata. Pertanto non vi è alcun vantaggio nel chiamare i metodi asincroni quando si sa che è un MemoryStream
. In realtà, è solo un sovraccarico completamente superfluo.
Ora, dimenticando che per un secondo solo per rispondere alla tua domanda sullo stile, il primo approccio è migliore perché non si assegna / programma una nuova Task
inutilmente (ad esempio con Task::Run
), ma non so perché tu non userebbe solo un’istruzione using()
in quell’approccio. Quindi ecco l’IMHO più pulito / semplice:
private async static Task WriteToStreamFirstVariantSimplified() { using(MemoryStream memoryStream = new MemoryStream()) { byte[] data = new byte[256]; try { await memoryStream.WriteAsync(data, 0, data.Length); } catch(Exception exception) { //Handling exception } } }