【问题标题】:Is it correct to levering a stream writer WriteLineAsync with WhenAll将流写入器 WriteLineAsync 与WhenAll 结合使用是否正确
【发布时间】:2022-11-04 00:54:27
【问题描述】:

我有一段代码,以异步方式编写文件(网络标准 2.1)

  • 创建一个热点任务列表,每行一个

  • 然后等待它们全部完成

  • 最后将 writer 缓冲区刷新到 memoryStream

         await using var memoryStream = new MemoryStream();
         await using var writer = new StreamWriter(memoryStream);
    
         var recordTasks = stringRecordsToWrite.Select(r => writer.WriteLineAsync(r));
    
         await Task.WhenAll(recordTasks);
    
         await writer.FlushAsync();
    
         var result = memoryStream.ToArray();
    

问题:有几个问题困扰着我:

  1. 有报道称,有时会跳过一些记录。 因此,我想知道,这种实施是否是根本原因。我试图在本地重现该问题,但不幸的是,没有成功
  2. Resharper 还强调,“writer”(在 SELECT 语句中)是一个捕获的变量,并位于外部范围内。会不会有问题?

    或者那些是虚假的痕迹,植入是好的,我应该尝试在其他地方找到原因

【问题讨论】:

  • StreamWriter 不是线程安全的。所以我不建议在它上面启动多个并发任务。
  • “我有一段代码,用来写文件”——这不会写入文件。这一切都在记忆中。
  • 1. 查看文档,我看到一些值得注意的事情:StreamWriternot thread-safe,但 WriteLineAsync() throws when the instance is busy。 2.这里没有问题,因为当await Task.WhenAll(recordTasks);返回时,所有对实例的延迟访问都将完成。 3. 总的来说,这感觉像是一个愚蠢的想法。

标签: c# asynchronous async-await streamwriter


【解决方案1】:

你有一个单身的溪流。并行异步写入它并没有真正意义——任何数量的事情都可能出错。我什至不知道MemoryStream 的线程安全是怎样的,我也看不到任何关于它的文档。 documentation for StreamWriter 明确指出:

默认情况下,StreamWriter 不是线程安全的。有关线程安全的包装器,请参阅 TextWriter.Synchronized。

我强烈建议您按顺序迭代,例如

foreach (var item in stringRecordsToWrite)
{
    await writer.WriteLineAsync(item);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多