2011-02-08 86 views
0

我有一個寫入的StreamWriter。此鎖定代碼是否有效?

當行數達到500時,關閉它並移動文件。

我已經添加了一個計時器,所以每隔5秒鐘關閉它並移動文件。

顯然,如果計時器開始並關閉StreamWriter,然後在MyMethod中嘗試寫入StreamWriter,它將拋出一個抖動。因此,我添加了一些鎖來嘗試和防止任何問題,所以如果計時器啓動它關閉StreamWriter,分配一個新的文件名,然後鎖定後,如果MyMethod試圖寫入它,一切都應該沒問題。

下面的代碼是否足夠處理您認爲的任何問題?

private readonly object objLock = new object(); 

    private StartUpMethod() 
    { 
     if (tmFileWriter == null) 
     { 
     tmFileWriter = new Timer(5000); 
     tmFileWriter.AutoReset = false; 
     tmFileWriter.Elapsed += new ElapsedEventHandler(tmFileWriter_Elapsed); 
     } 
    } 

    private void MyMethod() 
    { 
     lock (objLock) 
     { 
      if (_tempFilename == "") 
      { 
       _tempFilename = GenerateFileName(); 
      _tw = new System.IO.StreamWriter(_tempFilename); 
      } 
     } 

     //Do some processing 

     lock (objLock) 
     { 
      _tw.WriteLine(sql); 
      _filelineCount++; 
      if (_filelineCount > 500) 
      { 
       _tw.Close(); 
       System.IO.File.Move(_tempFilename, _tempFilename.Replace(".tmp", ".sql")); 
       _tempFilename = ""; 
       _filelineCount = 0; 
      } 
    } 

    private void tmFileWriter_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     tmFileWriter.Stop(); 

     lock (objLock) 
     { 
      if (_tw != null) 
      { 
       _tw.Close(); 
       System.IO.File.Move(_tempFilename, _tempFilename.Replace(".tmp", ".sql")); 
       _tempFilename = GenerateFileName(); 
       _tw = new StreamWriter(_tempFilename); 
      } 
     } 

     tmFileWriter.Start(); 
    } 
} 
+0

什麼是「搖擺」? – siride 2011-02-08 17:18:30

+0

例外,錯誤,黑洞:-) – Jon 2011-02-08 17:22:14

+0

@Jon:但爲什麼「搖擺」?那是一種俚語俚語嗎? – siride 2011-02-08 17:22:57

回答

2

這應該很好,因爲它可以保護文件免受多個線程的併發訪問。我唯一要做的就是將MyMethod中的兩部分結合起來。沒有理由在創建文件後釋放鎖,只是爲了再次獲得鎖才能寫入。因此,而不是:

lock 
{ 
    // Create file if necessary 
} 

lock 
{ 
    // write to the file 
} 

只要做到:

lock 
{ 
    // create file if necessary 
    // write to the file 
} 
1

我看到的唯一問題是,如果計時器觸發並有0線進入它可以使一個不必要的文件,但可能是行爲你要。

0

該代碼看起來像它會工作,但如果效率是一個問題,我會去使用緩衝區和使用原子交換的路線來更改輸出緩衝區的文件。

然後寫入緩衝區不會涉及任何鎖,只有寫入文件會。

1

我不是專家,但只是一個想法。如果計時器在退出MyMethod中的第二個鎖後直接觸發將會發生什麼情況。

private void MyMethod() { 
    lock{} 
    //Do processing 
    lock{} 
} 

它會嘗試移動已移動的文件嗎?