2013-03-26 32 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