2012-07-17 16 views
1

這個問題是第2部分的延續,任何有興趣看到我來自哪裏的人都可以參考第1部分和第2部分,但這不是必需的。寫入文件需要針對流量繁重的第3部分進行優化

write file need to optimised for heavy traffic

Write file need to optimised for heavy traffic part 2

現在我有一個工作片斷,相關部分低於:

public static class memoryStreamClass 
    { 
     static MemoryStream ms1 = new MemoryStream(); 

     public static void fillBuffer(string outputString) 
     { 
      byte[] outputByte = Encoding.ASCII.GetBytes(outputString); 

      ms1.Write(outputByte, 0, outputByte.Length); 

      if (ms1.Length > 8100) 
      { 
       emptyBuffer(ms1); 
       ms1.SetLength(0); 
       ms1.Position = 0; 
      } 
     } 

     static void emptyBuffer(MemoryStream ms) 
     { 
      FileStream outStream = new FileStream("c:\\output.txt", FileMode.Append); 

      ms.WriteTo(outStream); 
      outStream.Flush(); 
      outStream.Close(); 
     } 

上面的代碼工作正常,並沒有缺陷。它每輸出大約8KB的數據。

現在我嘗試多線程上面的代碼,以提高IO寫入瓶頸的性能和出現的問題。下面的片段就是我試圖嘗試的內容。

基本上我有2個相同的memoryStream,如果說ms1已滿,它將ms1寫入文件並在ms1寫入時切換到ms2,反之亦然。

public static class memoryStreamClass 
    { 
     static MemoryStream ms1 = new MemoryStream(); 
     static MemoryStream ms2 = new MemoryStream(); 
     static int c = 1; 

     public static void fillBuffer(string outputString) 
     { 
      byte[] outputByte = Encoding.ASCII.GetBytes(outputString); 

      if (c == 1) 
      { 
       ms1.Write(outputByte, 0, outputByte.Length); 

       if (ms1.Length > 8100) 
       { 
        c = 2; 

        Thread thread1 = new Thread(() => emptyBuffer(ms1)); 
        thread1.Start(); 

        ms1.SetLength(0); 
        ms1.Position = 0; 
       } 
      } 
      else 
      { 
       ms2.Write(outputByte, 0, outputByte.Length); 

       if (ms2.Length > 8100) 
       { 
        c = 1; 

        Thread thread2 = new Thread(() => emptyBuffer(ms2)); 
        thread2.Start(); 

        ms2.SetLength(0); 
        ms2.Position = 0; 

       } 
      } 
     } 

上面的代碼可以編譯和運行,但是輸出寫入並不總是8KB,並將其寫入方式過於頻繁(比我的單線程程序)。有人能啓發我並指出我的程序出了什麼問題嗎?非常感謝你

+1

@channs指出,如果您之前的任何問題都得到了正確答案,您應該將這些答案標記爲已接受。 – Jodrell 2012-07-17 16:40:41

+0

爲什麼不在http://codereview.stackexchange.com/上查看您的代碼? – HatSoft 2012-07-17 16:42:16

+1

將'static'和Streams結合起來不是一個好主意。當你將靜態和多線程結合起來時,你就會乞求糟糕的事情發生。你在這裏有什麼是錯的。將其廢棄並重新開始考慮多線程。 – 2012-07-17 16:45:44

回答

1

你的代碼非常糟糕,你使用兩個緩衝區來提高性能的想法幾乎肯定是過度優化。然而,有一個在這個代碼塊中的一個明顯的問題:

Thread thread1 = new Thread(() => emptyBuffer(ms1)); 
thread1.Start(); 

ms1.SetLength(0); 
ms1.Position = 0; 

這段代碼的作用是:

  • 啓動一個線程來處理一個緩衝
  • 立即明確表示緩衝

問題是,你的「清除」代碼將幾乎可以肯定在你的線程有機會開始之前執行(因爲一般來說,執行方法將在線程上下文更改之前完成)。所以,當您撥打emptyBuffer時,您的MemoryStream已經是空的。

你的靜力學是一個壞主意;如果您要將非靜態實例傳遞給emptyBuffer方法,然後設置ms1 = new MemoryStream(),則可能會有更好的功能代碼。但最終,這個代碼在概念上是有缺陷的,你應該看看重新設計。

+0

我打字幾乎完全一樣的東西。 +1 – 2012-07-17 17:02:48

+0

謝謝,我會重新思考我的代碼 – 2012-07-18 08:41:07