2013-03-26 8 views
6

Json.net ha le funzioni asincrone per la conversione di un oggetto JSON come:Json.net Async durante la scrittura su file

jsn = await JsonConvert.DeserializeObjectAsync<T> 

Ma quando voglio writea oggetto in un file di JSON sembra meglio a me fare direttamente utilizzando un file Stream.

quindi penso che dovrebbe essere qualcosa di simile:

var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite); 

    using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0)) 
    { 
     using (StreamWriter sw = new StreamWriter(fileStream.AsStreamForWrite())) 
     { 
      using (JsonWriter jw = new JsonTextWriter(sw)) 
      { 
       jw.Formatting = Formatting.Indented; 

       JsonSerializer serializer = new JsonSerializer(); 
       serializer.Serialize(jw, obj); 
      } 
     } 

Ma d'oggetto JsonSerzializer non riesco a trovare metodi asincrone. Inoltre, penso che le operazioni di I/O non dovrebbero essere inserite in una propria discussione.

Qual è l'approccio consigliato?

risposta

9

Json.NET in realtà non supporta la de/serializzazione asincrona. I metodi asincroni su JsonConvert sono solo wrapper su metodi sincroni che li eseguono su un altro thread (which is exactly what a library shouldn't do).

Penso che l'approccio migliore sarebbe quello di eseguire il codice di accesso ai file su un altro thread. Questo non ti darà tutti i vantaggi di async (sprecherà un thread), ma non bloccherà il thread dell'interfaccia utente.

+0

Grazie per la segnalazione. Mi stavo già chiedendo come un stringoperation potrebbe essere asincrono senza thread .. Il Streaming potrebbe essere reso asincrono. Forse quello sarebbe un Feature per Json.net ma ovviamente non è ancora stato impiantato. Quindi grazie per la risposta. –

+0

Questa sarebbe una semplice operazione da completare: creare un fork async di JSON.Net. Il problema, però, è che ci vorrà molto tempo - qualcuno ha circa 80 ore di anticipo? se non di più? – Todd

4

Vedere anche questo codice, che utilizza il modo corretto asincrono (ad esempio non creerà enormi array di byte per evitare allocazioni di memoria LOH, non attenderà il completamento dell'operazione IO).

using (var file = File.Open(destination, FileMode.Create)) 
{ 
    using (var memoryStream = new MemoryStream()) 
    { 
     using (var writer = new StreamWriter(memoryStream)) 
     { 
      var serializer = JsonSerializer.CreateDefault(); 

      serializer.Serialize(writer, data); 

      await writer.FlushAsync().ConfigureAwait(false); 

      memoryStream.Seek(0, SeekOrigin.Begin); 

      await memoryStream.CopyToAsync(file).ConfigureAwait(false); 
     } 
    } 

    await file.FlushAsync().ConfigureAwait(false); 
} 

intero file: https://github.com/imanushin/AsyncIOComparison/blob/0e2527d5c00c2465e8fd2617ed8bcb1abb529436/IntermediateData/FileNames.cs

+1

IMHO, questa risposta è migliore della risposta accettata, considerando che la risposta accettata ha completamente ignorato il fatto che l'utente stava tentando di eseguire l'IO e non offre alcun esempio reale. –