2013-03-26 16 views
6

Json.net hat die Asynchron-Funktionen zur Umwandlung eines Objekts zu JSON-Datei wie:Json.net Async zu schreiben, als

jsn = await JsonConvert.DeserializeObjectAsync<T> 

Aber wenn ich Objekt zu einem json WRITEA wollen Datei scheint es mir besser Verwenden Sie direkt einen Datei-Stream.

Also ich denke, es so etwas wie dies sein sollte:

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

Aber auf der JsonSerzializer Object ich nicht async Methoden finden. Ich denke auch, dass IO-Operationen nicht in einem eigenen Thread platziert werden sollten.

Was ist der empfohlene Ansatz?

Antwort

9

Json.NET unterstützt asynchrone De-/Serialisierung nicht wirklich. Die asynchronen Methoden unter JsonConvert sind nur Wrapper über die synchronen Methoden, die sie in einem anderen Thread ausführen (which is exactly what a library shouldn't do).

Ich denke, der beste Ansatz hier wäre, den Dateizugriffscode auf einem anderen Thread auszuführen. Dies gibt Ihnen nicht die vollen Vorteile von async (es wird einen Thread verschwenden), aber es wird nicht den UI-Thread blockieren.

+0

Vielen Dank für den Hinweis. Ich habe mich schon gefragt, wie eine Stringoperation asynchronen Thread sein könnte. Das Streaming könnte asynchron gemacht werden. Vielleicht wäre das ein Feature für Json.net, aber offensichtlich ist es noch nicht implementiert. Also Danke für deine Antwort. –

+0

Das wäre eine einfache Aufgabe - eine asynchrone Verzweigung von JSON.Net zu erstellen. Das Problem ist jedoch, dass es lange dauern würde - jeder hat etwa 80 Stunden Zeit? wenn nicht mehr? – Todd

4

Siehe auch diesen Code, der den richtigen asynchronen Weg verwendet (z. B. werden keine großen Byte-Arrays erzeugt, um LOH-Speicherzuweisungen zu vermeiden, es wird nicht auf den IO-Vorgang gewartet).

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

ganze Datei: https://github.com/imanushin/AsyncIOComparison/blob/0e2527d5c00c2465e8fd2617ed8bcb1abb529436/IntermediateData/FileNames.cs

+1

IMHO, diese Antwort ist besser als die angenommene Antwort, unter Berücksichtigung der akzeptierten Antwort völlig ignoriert die Tatsache, dass der Benutzer versuchte, IO durchzuführen und bietet kein echtes Beispiel. –