2008-11-17 107 views
2

下面的代碼只是一個簡單的例子來說明我的問題:打開文件進行共享寫

using System; 
using System.IO; 
using System.Diagnostics; 
using System.Threading; 

namespace ConsoleApplication5 
{ 
    class Program 
    { 
     static string LogFile = @"C:\test.log"; 

     static void Main(string[] args) 
     { 
      for (int i = 0;i<10;i++) 
      { 
       new Thread(new ParameterizedThreadStart(DoWork)).Start(i); 
      } 
      Console.ReadKey(); 
     } 

     static void DoWork(object param) 
     { 
      int count = (int)param; 

      try 
      { 
       using (FileStream fs = new FileStream(LogFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) 
       using (StreamWriter sw = new StreamWriter(fs)) 
       { 
        sw.WriteLine(DateTime.Now + " - Start " + count.ToString()); 
        Thread.Sleep(2000); // simulate doing some work 
        sw.WriteLine(DateTime.Now + " - End " + count.ToString()); 
       } 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(count.ToString() + ": " + e.Message); 
       return; 
      } 
      Console.WriteLine(count.ToString() + ": Done."); 
     } 
    } 
} 

這裏的問題是,通常只有一個入口使其進入文件,即使我調用該方法10倍。該文件應該打開以允許共享。據我所知,沒有例外被拋出。這是怎麼回事?

在實際的代碼,這個例子陰影,每次調用DoWork的實際上是一個獨立的進程,但測試表明,其結果是,如果我可以修復它在這裏我可以有解決它的same--。

回答

4

沒有什麼奇怪的事情在這裏。想象一下,你有一個文件「a.txt」,你用記事本打開它10次。之後,您將更改文件的內容並將其保存在記事本的每個實例中。當然,最後一次保存是保存到文件中的,因爲它重寫了以前的9次保存。

我想你已經得到了相同的行爲在這裏。所有文件同時打開,因爲每個處理中都有一個Thread.Sleep。所以我保存的i文件會覆蓋前面的保存(i-1)。

編輯:嘗試刪除Thread.Sleep(2000),您將有更多的日誌在文件中。

+0

當然這不奇怪:)我只是想考慮非奇怪的事情是怎麼回事哪。這很有道理,謝謝。 – 2008-11-17 18:07:43

1

使用SyncLock這可以確保只有一個線程打開一次文件。 與此同時,其他進程不會崩潰,而是等待queue