2012-12-12 157 views
0

嘿所以我有一個頻繁調用的記錄類,有時當它重複調用快速時,它會拋出一個異常,該文件已被另一個應用程序使用。我們找到解決方法的唯一方法就是捕捉異常,然後嘗試再次打開它......我不確定如何正確處理這個問題。C#文件經常打開,已經打開的異常

/// <summary> 
    /// Open a log file based on a date 
    /// </summary> 
    /// <param name="date"> Date of the file to open </param> 
    public static void OpenLogFile(DateTime date) 
    { 
     while (true) 
     { 
      try 
      { 
       logStream = File.Open("Logs/ems." + date.ToString("yyyy-MM-dd") + ".log", FileMode.Append); 
       break; 
      } 
      catch 
      { 
       continue; 
      } 
     } 
    } 




    /// <summary> 
    /// Writes to a log file the specified input 
    /// </summary> 
    /// <param name="input"> Content to write to the log file </param> 
    public static void Log(string className, string methodName, string input) 
    { 
      OpenLogFile(DateTime.Now); 

      using (StreamWriter s = new StreamWriter(logStream)) 
      { 
       s.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + '[' + className + '.' + methodName + "] " + input); 
      } 

      CloseLogFile(); 
    } 




    /// <summary> 
    /// Closes the current log file 
    /// </summary> 
    public static void CloseLogFile() 
    { 
     if (logStream != null) 
     { 
      logStream.Close(); 
      logStream = null; 
     } 
    } 
+0

我猜這是一個多線程應用程序?您可以使用AutoResetEvent來控制對文件的訪問。 – itsme86

回答

6

由於這是一個日誌文件,我認爲明顯的(和正確的)解決方案是在程序執行期間保持打開文件。

如果您不想使用已經實現的第三方記錄器,如Apache的log4net,那麼您可以編寫自己的小型記錄器類,該類使用線程安全機制將文本行寫入文件。

它可能是一個static類,或單身。通常,程序開始和結束時的執行是相當可預測的,所以應該清楚在哪裏初始化,並關閉對象/類。

+2

確保每次寫入後都使用刷新(因此日誌保持最新狀態)。 – Trisped

+0

打開文件相對於實際寫入文件可能會有相當高的開銷,如果絕對必要,我只會關閉它。 –

+0

我會在你的日誌功能中添加一個鎖(threadObject)。如果你正在寫這個文件的話,那麼我會把它打開。 Microsoft企業庫是另一種現成可用的日誌記錄解決方案。它會創建文件,如果在特定尺寸後關閉,請在這麼長時間後清除,洗衣服,...... – Rob4md

1

需要一點點的命令,而不是一個免費的磁盤。將日誌消息存儲在隊列中,並使單個線程出隊並寫入項目。