2017-06-29 222 views
-1

我目前正在開發一個程序的子系統,需要將數據寫入磁盤。我已經將此作爲一個多線程生產者 - 使用者模型實現,它在一個線程中生成數據包,並將它們放入一個隊列中,並將它們寫入另一個線程中的磁盤。C#,在單獨的線程中執行事件處理程序

程序必須使用最少的CPU資源,因此爲了避免寫入線程在等待數據包到達時閒置,我擴展了ConcurrentQueue類,以便在將數據包添加到隊列時觸發事件,因此寫入功能僅在存在可用數據時纔有效。這裏的生成函數:

 while (writeData) 
     { 
      for (int i = 0; i < packetLength; i++) 
      { 
       packet.data[i] = genData(); 
      } 

      packet.num++; 

      // send packet to queue to be written 
      // this automatically triggers an Event 
      queue.Enqueue(packet);  

     } 

我的問題是,我一直無法弄清楚如何將事件處理程序分配(即:寫操作),以一個單獨的線程 - 據我所知,C#中的事件處理程序在觸發事件的同一個線程上運行。

我想過使用ThreadPool,但我不確定隊列中的數據包是按順序還是並行寫入。 。編寫並行數據包也不會在這方面的工作,因爲它們都被寫入到同一個文件,並在他們到達的順序來寫這是我到目前爲止有:

private void writeEventCatch(object sender, EventArgs e) 
    { 
     // catch event and queue a write operation 
     ThreadPool.QueueUserWorkItem(writeToDisk); 

    } 

    private void writeToDisk(Object stateInfo) 
    { 
     // this is a struct representing the packet 
     nonCompBinData_P packet; 

     while (queue.TryDequeue(out packet)) 
     { 

      // write packet to stream 
      serialiser.Serialize(fileStream, packet); 
      packetsWritten++; 

     } 

    } 

任何有識之士進入這將是感激地收到!

+0

我們應該怎樣幫助你,而無需任何代碼?請通過閱讀[問]來嘗試改進您的問題。 - 歡迎來到SO! :) – Fildor

+1

我的第一個想法將是一個普通的舊線程,從[BlockingCollection](https://msdn.microsoft.com/en-US/library/dd267312(v = vs.110).aspx)起作用,直到被告知停止。然後,您只需要共享該集合並將其填充到一個線程中,表示消費者線程將執行該工作,並且該集合處理併發性。 – Fildor

+0

爲什麼你需要多線程呢?單線程不夠快嗎? –

回答

0

while(queue.TryDequeue(out packet))將會退出,只要沒有要出隊的數據包。你需要做的是啓動單線程寫操作deque工作項目和寫入數據到磁盤。項目將逐個出隊並且爲了他們到達。