這是一個簡單的例子如何保證在多線程中使用異常寫入文件?
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new Thread(() => Method1()).Start();
new Thread(() => Method2()).Start();
Console.Read();
}
private static void Method1()
{
using (StreamWriter sw = new StreamWriter(@"h:\data.txt"))
{
int i = 100000000;
while (true)
{
Thread.Sleep(100);
sw.WriteLine(i);
i++;
}
}
}
private static void Method2()
{
Thread.Sleep(6000);
throw null;
}
}
}
的StreamWriter如果發生異常太早,在另一個線程不會將數據寫入到文件中。發生異常時,文件data.txt爲空。
我打這種情況一點,發現了一堆解決方法:
如果我增加了異常的線程睡眠間隔(和著作之間減少間隔成文件),該文件將充滿數據。這不是一個選擇,因爲我不知道什麼時候發生異常。
由於以前的解決方法,我可以減少流編寫器的緩衝區大小。但它似乎不工作,如果我把它設置得太小 - 例如,此代碼
FileStream fs = new FileStream(@「h:\ data.txt」,FileMode.Create);
使用(StreamWriter的SW =新的StreamWriter(FS,Encoding.Default,10))
不起作用,因爲只出現在第一寫入操作時約385的整數中的緩衝器正在等待寫入文件。
如果在發生異常之前關閉寫入器,文件將被填充。但這不是一個好的選擇 - 我必須每秒寫入1到10次的文件。如此頻繁地打開和關閉作家並不是一個好主意,是嗎?
我能趕上這樣的
私有靜態無效方法2)異常( {
try { Thread.Sleep(6000); throw null; } catch { Console.WriteLine("Exception!"); }
}
一切就會OK - 沒有應用程序終止和文件將被填充包裝。但情況並非如此 - 我無法控制發生異常的時間和地點。我試圖在任何地方使用try-catch,但我可能會錯過一些東西。
所以情況是:StreamWriter的緩衝區未滿,在另一個線程中發生異常並且未捕獲,因此應用程序將被終止。如何不丟失這些數據並將其寫入文件?
您是否嘗試'刷新'流而不是關閉它。這應該照顧到保存數據到文件,同時讓流打開並接受更多的數據 – Sidewinder94
也就是說,我會建議你檢查一下['lock'](https://msdn.microsoft.com/en- us/library/c5kehkcz.aspx)關鍵字和['Mutex'](https://msdn.microsoft.com/en-us/library/system.threading.mutex(v = vs.110).aspx)對象存在以解決這些併發問題 – Sidewinder94
如果您簡單地在'try {} catch {} finally {}'塊中並在'finally'塊中封裝Main方法等待工作Thread可以完成執行 – Fabjan