0

为什么当程序点击//这里。它因未处理的异常而崩溃:System.ObjectDisposedException:无法写入已关闭的 TextWriter。?Print() 方法在LogClose()之前调用。我想要实现的是如果它点击这里然后打印出消息和程序退出

foreach (string sf in ff)
{

    if (File.Exists(sf))
    {
        File.Move(sf, copy_dir + "\\" + sf);
    }
    else
    {
        //HERE
        l.ExitAndOut("Error: " + sf + " not found");
    }
}



class logger {
StreamWriter sw = new StreamWriter("SpireCli.log");

public void Print(string log)
{
    DateTime ts = DateTime.UtcNow;
    sw.WriteLine(ts + " " + log);
}

public void ExitAndOut(string log)
{
    string Program_Exit = "Program Exit";

    Console.WriteLine(log);
    Console.WriteLine(Program_Exit);
    Print(log);
    Print("Exit");
    LogClose();
    Environment.Exit(1);
}

public void LogClose()
{
    sw.Close();
}
}
4

3 回答 3

2

如果我是你,我会使用Log4Net而不是重新发明轮子。log4Net 为您提供的一件事是能够一次将日志消息直接发送到多个数据存储。配置 aConsoleAppender和 a FileAppenderor RollingFileAppender,您将获得控制台输出以及日志文件输出,只需一次log.Warn()调用即可。

但是,如果您要自己滚动,日志文件的重点是以稳健的方式记录事物:如果您在每次 write() 时不刷新未写入缓冲区的情况下让底层TextWriter及其Stream打开的持续时间,如果发生崩溃,您可能会丢失数据。为此,像这样的课程应该可以做到。它在每次写入时打开/关闭文件,确保一切保持有序状态:

class MyLogger
{
  private string LogFilePath { get ; set ; }
  public MyLogger( string fileName )
  {
    this.LogFilePath = fileName ;
    return ;
  }

  public void Print( string format , params object[] args )
  {
    using ( TextWriter logfile = new StreamWriter( "" , true , Encoding.UTF8 ) )
    {
      WriteLine( logfile , false , format , args ) ;
    }
    return ;
  }

  private void WriteLine( TextWriter writer , bool echoToConsole , string format , params object[] args )
  {
    string   message = string.Format( format , args ) ;
    DateTime dtNow   = DateTime.Now ;
    const string logFormat = "{0:yyyy-MM-dd hh:mm:ss.ttt}: {1}" ;
    writer.WriteLine( logFormat , dtNow , message ) ;
    if ( echoToConsole )
    {
      Console.WriteLine( logFormat , dtNow , message ) ;
    }
    return ;
  }

  public void ExitAndOut( string format , params object[] args )
  {
    using ( TextWriter logfile = new StreamWriter( "" , true , Encoding.UTF8 ) )
    {
      WriteLine( logfile , true , format , args ) ;
      WriteLine( logfile , true , "Program Exit" ) ;
    }
    Environment.Exit(1) ;
    return ; // unreachable code
  }

}
于 2013-04-24T21:06:37.060 回答
1

如果要关闭 StreamWriter,则必须打开它。

class logger {

public void LogOpen()
{
    StreamWriter sw = new StreamWriter("SpireCli.log");
}

public void Print(string log)
{
    DateTime ts = DateTime.UtcNow;
    sw.WriteLine(ts + " " + log);
}

public void ExitAndOut(string log)
{
    string Program_Exit = "Program Exit";

    Console.WriteLine(log);
    Console.WriteLine(Program_Exit);
    LogOpen();
    Print(log);
    Print("Exit");
    LogClose();
    Environment.Exit(1);
}

public void LogClose()
{
    sw.Close();
}
}

由于 StreamWriter 实现了 IDisposable,更好的方法是你应该使用using语句。

于 2013-04-24T20:50:19.940 回答
1

您需要将代码重写为更像这样的东西(伪):

public static void Parse( )
{
   using( var sw = new StreamWriter(@"c:\file.txt") )
   { 
       foreach (string sf in ff)
       {
           if (File.Exists(sf))
              File.Move(sf, copy_dir + "\\" + sf);
           else
              Print( sw, "Error: " + sf + " not found");
       }
   }
}

public static void Print(StreamWriter s, string log)
{
    DateTime ts = DateTime.UtcNow;
    s.WriteLine(ts + " " + log);
}
于 2013-04-24T20:37:22.030 回答