2017-06-29 177 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工作项目和写入数据到磁盘。项目将逐个出队并且为了他们到达。