3

我的应用程序中有一个非常简单的日志记录机制,它会定期将一行写入文件(日志库对我的需要来说是多余的),看起来像这样:

private string logfile = @"C:\whatever.log";

public void WriteLine(string line)
{
   using(FileStream fs = File.Open(logfile, FileMode.Append))
   {
    // Log Stuff
   }
}

因此,每当我调用该方法时,都会在日志记录完成后创建并处理一个新的 FileStream。所以我考虑使用已经实例化的对象来防止新对象的不断创建:

private string logfile = @"C:\whatever.log";
private FileStream myStream = File.Open(logfile, FileMode.Append);

public void WriteLine(string line)
{
   using(myStream)
   {
    // Log Stuff
   }
}

但是,由于范围问题, MSDN 参考不鼓励这样做(最后一个示例)。在这种情况下怎么办?我的第一个示例中的开销可以忽略不计吗?

4

3 回答 3

3

The using statement doesn't do anything else than calling the Dispose() method of the object.
So considering your second example, after the first call to the WriteLine(string) method the filestream is disposed. So any other call, after the first one, to this Method will result in an exception.

Using the File.AppendText() method like Chris had suggested in the comment would be a way to go. But keep in mind, that using this or any other File... method will also open a stream and close and dispose it afterwards.
It will just result in less code.

于 2013-09-02T11:17:42.980 回答
3

第二种方法也会在您每次调用时处理流,WriteLine因为您也在使用using-statement。MSDN 不鼓励这种方法,因为myStream即使对象被释放,变量仍然“存在”。所以这样更容易出错。

如果您经常需要使用这种方法,您应该考虑使用using“外部”或使用try-catch-finally

var myLogger = new MyLogger();
try
{      
    // here is your app which calls myLogger.WriteLine(...) often
}
catch(Exception ex)
{
    // log it
}
finally
{
    myLogger.Dispose(); // myLogger is your Log class, dispose should call myStream.Dispose();
}
于 2013-09-02T11:19:52.897 回答
1

开销可能不可忽略,但这可能不是重点。

当您使用using时,资源的创建、获取和使用过的资源的处置是很好的范围。你知道它从哪里开始,在哪里使用,在哪里结束。

如果你选择第二种情况,你知道它从哪里开始(它是在创建包含类时),但在那之后,你就没有平台保证的方法来控制它的使用位置,以及资源在哪里(如果有的话)处置。

如果这是关键代码,您可以自己执行此操作,并且您的包含类正确实现IDisposable 模式,但这可能很棘手,不适合胆小的人:)

但是,您在问题“日志库对我的需求来说太过分了”中说,所以我认为您可以通过最小的开销来解决问题。恕我直言,您应该可以使用其中一种现成的File方法,例如File.AppendAllText

public void WriteLine(string line)
{
   //add an enter to the end
   line += Environment.NewLine;
   File.AppendAllText(logfile, line);
}

File.AppendAllLines

public void WriteLine(string line)
{
   File.AppendAllLines(logfile, new []{line});
}
于 2013-09-02T11:14:14.933 回答