2012-06-29 77 views
0

背景:我有幾個不同的線程,每個線程都需要寫入日誌文件(.txt)。我需要一種在線程之間共享這個文件的方式,但我不知道如何去做這件事,我已經閱讀了可能使用某種類型的隊列,並輪詢此隊列將消息推送到文本文件等。或者我是否需要鎖定文件,然後在隊列完成後纔將隊列中的消息寫入隊列?最佳做法 - 鎖定文件和線程之間的共享

目前我寫的是這樣的;

fileToWrite = new System.IO.StreamWriter(DeviceManager.logPath + correctDateTimeFormat); 

但我收到錯誤消息;

The process cannot access the file 'filename' because it is being used by another process. 

我只能假設多個線程正試圖同時訪問它。

任何人都可以指出我正確的方向,我應該採取什麼方法?

+0

也許這符合你的需求? http://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile.aspx – kenny

+6

去Log4Net它已經這樣做 – GETah

+0

log4net或(我更喜歡)NLog。雖然它不是'如何以正確的方式鎖定這些文件'的答案,但它確實解決了這個問題。 – hometoast

回答

2

這是你在這裏面臨的兩個不同的問題。

  1. 再次打開文件時,它被關閉之前 - 這可以通過適當的共享標記
  2. 同步訪問它打開來完成。這個可以通過讓一些互斥體一次只允許一個線程訪問文件來完成。這很重要,因爲否則,您可能會同時將線程寫入文件,這可能會導致問題,如消息在自我之間交叉。

FileStream constructorFileSharing參數可以幫助您在關閉它們之前從少量線程打開文件。

但是,爲了您的需要,如果您想在一個位置集中訪問您的文件(例如,日誌文件)會更好(創建一個類,其中有一個實例將控制對此特定文件的訪問)並確保它會通過鎖定某些私有互斥鎖來同步來自不同線程的訪問,因此您不會同時從少量線程寫入文件。

很簡單的例子,這就需要建立:

class Logger : IDisposable 
{ 
    private FileStream file; //Only this instance have a right to own it 
    private StreamWriter writer; 
    private object mutex; //Mutex for synchronizing 

    public Logger(string logPath) 
    { 
     file = new FileStream(logPath); 
     writer = new StreamWriter(file); 
     mutex = new object(); 
    } 

    // Log is thread safe, it can be called from many threads 
    public void Log(string message) 
    { 
     lock (mutex) 
     { 
      writer.WriteLine(message); 
     } 
    } 

    public void Dispose() 
    { 
      writer.Dispose(); //Will close underlying stream 
    } 
} 

再次,這是很簡單的,只顯示了我們正試圖在這裏實現基本規則。

很少有其他的選擇,你在這裏:

  1. 使用準備使用日誌記錄庫(log4net的或NLOG(我更喜歡個人))
  2. 日誌可能會添加消息到隊列中,你可以有另一個線程內部的記錄從隊列中讀取消息,並將其寫入,這樣一來,記錄器的調用者將不必等待日誌消息來完成這個職位,你如何在WPF 使用log4net的記錄
+0

第2點看起來很有趣,你有什麼參考我可以看看特別? –

+0

@ Shane.CI爲第1和第2點添加了一些內容。但是,如果您只需要日誌記錄功能,並且不想自己編寫有趣的庫,最好使用現成的庫,它們工作良好並易於集成與WinForms,WPF和任何其他應用程序。 –

+0

感謝您的意見:)肯定地闡明瞭一些情況,我想我只會使用log4net,因爲這些似乎是最喜歡的選擇。 –

1

http://codetechnics.blogspot.com/2010/09/how-to-configure-initialize-and-using.html 如果您收到錯誤無法找到類型或命名空間名稱'log4net'(您是否缺少using指令或程序集引用?)

因爲log4net的顯然需要訪問System.Web.dll程序,這是不包含在客戶端配置文件

打開項目的屬性頁,並設置目標框架.Net Framework 4並保存您的更改。

+0

是否有一個原因,我的日誌文件似乎只是過度填充[header] [footer] [header] [footer]等等等等? –

+0

沒關係,修正:) –

相關問題