2013-03-26 33 views
6

Json.net具有異步功能將對象轉換爲JSON,如:Json.net異步時,文件

jsn = await JsonConvert.DeserializeObjectAsync<T> 

但是,當我想WRITEA對象到JSON文件似乎不如我直接使用文件流。

所以我想應該是這樣的:

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

但在JsonSerzializer對象我找不到異步方法。另外我認爲IO操作不應該放在自己的線程中。

推薦的方法是什麼?

回答

9

Json.NET並不真正支持異步反序列化/序列化。 JsonConvert上的異步方法僅僅是在另一個線程上運行它們的同步方法的封裝(which is exactly what a library shouldn't do)。

我認爲這裏最好的辦法是在另一個線程上運行文件訪問代碼。這不會給你async的全部好處(它會浪費一個線程),但它不會阻塞UI線程。

+0

感謝您指出了這一點。我已經在想如何一個字符串操作可以是非線程異步.. 流可以做成異步。也許這將是Json.net的一個功能,但顯然它還沒有被執行。所以謝謝你的回答。 – 2013-03-27 06:49:32

+0

這將是一個簡單的任務來完成 - 製作JSON.Net的異步分支。但問題是,這需要很長時間 - 任何人都可以節省大約80個小時的時間?如果不是更多? – Todd 2015-04-24 12:08:32

4

另請參閱此代碼,它使用正確的異步方式(例如,它不會創建巨大的字節數組以避免LOH內存分配,它不會等待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); 
} 

整個文件:https://github.com/imanushin/AsyncIOComparison/blob/0e2527d5c00c2465e8fd2617ed8bcb1abb529436/IntermediateData/FileNames.cs

+1

恕我直言,這個答案比接受的答案要好,考慮到接受的答案完全忽略了用戶試圖執行IO的事實,並沒有提供真實的例子。 – 2017-03-22 15:31:35