【问题标题】:"using" instruction overhead when writing a file in c#在 C# 中写入文件时的“使用”指令开销
【发布时间】:2013-11-22 13:44:32
【问题描述】:

我需要在两个单独的文件中写入两个日志:一个每秒写入 530 个字符 30 次,另一个每秒写入 50 个字符 60 次。我将要写入的数据保存在两个单独的变量中,并分别每 n 帧和 m 帧写入一次。编写我使用的变量:

using (StreamWriter writer = new StreamWriter(newFileName, true))

然后

writer.Write(data)

现在...我知道使用“使用”的优点,但我想知道:它有开销吗?为什么不在代码开头声明一个 StreamWriter 并在需要时使用它?

【问题讨论】:

  • 完成后立即关闭/处置非托管资源。
  • 直接回答你的问题:你想用 using 包围一个资源而不是仅仅声明它并在使用它时访问它的原因是因为意外退出。如果代码中的某些内容引发错误,或者进程因任何原因停止,那么您将没有机会进行清理。您需要确定意外退出的可能性有多大,要捕获哪些异常以及在这些情况下是否可以接受清理。
  • 基于@Tigran 的回答,看看这个SO post,它详细介绍了一个类似的场景。
  • 谁在使用上述日志文件以及多久使用一次?如果您没有关闭流或 Flush() 它们,那么任何试图读取日志文件的人都可能看不到最新数据(或者甚至可能出错,这取决于他们如何读取数据)。需要考虑的事情......

标签: c# streamwriter using-statement


【解决方案1】:

好吧,如果您需要以这样的速度和频率写入数据,我建议根本不要使用using,因为最后的using关闭并处理流对象,因此在下一个请求中,您需要重新初始化并重新打开stream,这需要花费。

因此,只需打开它们并在需要时一直使用它。手动处理后。

【讨论】:

  • 为什么会投反对票?这显然是他能做的最好的事情。使用这种频率会产生很多成本。他应该使用 tra...catch finally 构造来防范打开的句柄,但这种构造应该是更好的解决方案。有时名义上的最佳解决方案不适合。这大概就是这个时候了。
【解决方案2】:

using 语句本身没有任何实际开销。但是,可以打开和关闭非托管资源。如果您打算让它保持打开状态,而不是利用using,那么进行日志记录的类需要实现IDispoable。此外,在Dispose 方法中,它需要正确处理流。最后,利用记录器的消费者,确保它在利用它时使用using 命令。

【讨论】:

    【解决方案3】:

    using 抛出一个 try catch 块:

    using (StreamWriter writer = new StreamWriter(newFileName, true)) 
    {
        //do stuff
    }
    

    相当于:

    StreamWriter writer = new StreamWriter(newFileName, true);
    try
    {
        //do stuff
    }
    finally
    {
       if (writer!= null)
          ((IDisposable)writer).Dispose();
    }
    

    http://msdn.microsoft.com/en-us/library/yh598w02%28v=vs.110%29.aspx

    手动调用 .Dispose() 函数会更快,或者正如 Tigran 指出的那样,根本不要处理。但是,要小心。

    【讨论】:

    • 是的,我知道那个翻译 :) 问题是来自这种写入文件方式的流的连续打开/关闭/重新打开。
    • @Marco:如果您决定保持打开状态,您可能需要检查 flush .Flush() 方法。它可能会帮助您同步实际的写入操作。 msdn.microsoft.com/en-us/library/… 不过要小心,这很耗时。
    猜你喜欢
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    相关资源
    最近更新 更多