2013-09-21 57 views
2

好吧,我的程序有大約30個線程,我需要記錄通過每個線程收集的一些信息。C#寫入文本文件安全地堆積線程

我這樣做的方法是:在類Program中創建一個公共靜態StringBuilder,然後每隔幾分鐘,每個線程將調用AppendLine方法到這個StringBuilder實例。然後,每隔30分鐘,另一個專用於使用StreamWriter進行寫入的線程完全可以做到這一點。

例如:

public class Program 
{ 
    public static StringBuilder sb = new StringBuilder(); 
    public static void Main(string[] args) 
    { 
     // Start all threads 
    } 
} 

public class Example 
{ 
    Thread t1 = new Thread(() => 
    { 
     while(true) 
     { 
      DoSomething(); 
     } 
    }); 

    Thread logThread = new Thread(() => 
    { 
     while(true) 
     { 
      using(StreamWriter writer = new StreamWriter(Path)) 
      { 
       writer.Write(Program.sb); 
      } 
     } 
    }); 

    public static void DoSomething() 
    { 
     // Will do something for a few minutes. 
     Program.sb.AppendLine("Some text gathered before...different everytime!"); 
    } 
} 

這是這樣做的好方法嗎?

感謝

回答

2

沒有,StringBuilder不是在同一時間可能會損壞它線程使用它安全的,所以多線程。

使用lock關鍵字將訪問同步到StringBuilder。讓它私有,並提供公有方法安全地與它的工作:

private static StringBuilder _sb = new StringBuilder(); 
private static object _sbSync = new Object(); 

public static void AppendLine(string line) { 
    lock (_sbSync) { 
    _sb.appendLine(line); 
    } 
} 

public static string GetLines() { 
    lock (_sbSync) { 
    string result = _sb.ToString(); 
    _sb = new StringBuilder(); 
    return result; 
    } 
} 
+0

非常感謝:) – user2764359

0

我會建議不要讓每個那些線程寫入文件,但寫入共享內存資源,而不是(一個Singleton,您可以訪問從每個線程),然後讓Singleton在必要時寫入文件 - 比如在程序結束時。這樣只有一個線程訪問I/O,你會更安全。

很顯然,你編寫的Singleton也必須是線程安全的,所以你必須用鎖來控制對它的寫操作。

祝你好運!

1

我們可以使用ReaderWriterLockSlim http://www.johandorper.com/log/thread-safe-file-writing-csharp

private static ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim(); 

public void WriteToFile(string text, string path) 
{ 
    _readWriteLock.EnterWriteLock(); 
    using (StreamWriter sw = new StreamWriter(path, true)) 
    { 
     sw.WriteLine(text); 
     sw.Close(); 
    } 
    _readWriteLock.ExitWriteLock(); 
}