C# 在C中的一个单独线程上快速记录数据#

C# 在C中的一个单独线程上快速记录数据#,c#,logging,file-io,thread-safety,queue,C#,Logging,File Io,Thread Safety,Queue,我们正在开发一个应用程序,它可以连续地从许多外部硬件设备读取数据。数据速率介于0.5MB到10MB/秒之间,具体取决于外部硬件配置 目前正在BackgroundWorker上读取外部设备。尝试使用同一个BackgroundWorker将获取的数据写入磁盘似乎不是一个好的解决方案,因此我们要做的是,将要写入文件的数据排入队列,然后让另一个线程将数据移出队列并写入文件。请注意,数据将有一个生产者和一个消费者 为此,我们正在考虑使用同步队列。但是我们认为这个轮子已经被发明了很多次了,所以我们应该向so

我们正在开发一个应用程序,它可以连续地从许多外部硬件设备读取数据。数据速率介于0.5MB到10MB/秒之间,具体取决于外部硬件配置

目前正在BackgroundWorker上读取外部设备。尝试使用同一个BackgroundWorker将获取的数据写入磁盘似乎不是一个好的解决方案,因此我们要做的是,将要写入文件的数据排入队列,然后让另一个线程将数据移出队列并写入文件。请注意,数据将有一个生产者和一个消费者

为此,我们正在考虑使用同步队列。但是我们认为这个轮子已经被发明了很多次了,所以我们应该向so社区征求一些意见


如果您对我们应该注意的事项有任何建议或意见,我们将不胜感激。

您尝试过了吗

我相信您的队列将非常正常。但要确保使用有效的存储/检索数据的方法,而不是彻底检查内存分配/释放的日志记录过程。我会寻找一些预先分配的内存缓冲区,并将其用作循环队列。

u可能需要查询

代码

protected Queue<Byte[]> myQ;
or
protected Queue<Stream> myQ;

//when u got the content try
myQ.Enque(...);

我会做888先生所做的组合

基本上你有两个背景工人, 从硬件设备读取数据的设备。 将数据写入磁盘的人

硬件后台工作人员:
在中的硬件数据上添加卡盘。不管你用什么格式

编写后台工作程序
如果需要,解析数据并转储到磁盘

这里要考虑的一件事是把数据从硬件到磁盘一样快到最重要的位置? 如果是,那么我将在while循环中使用100ms或10ms睡眠,并检查que是否有数据的循环中使用write brackground测试。


如果没有,那么我会让它睡眠一个模拟量(假设你从硬件获得的速度周期性地改变),并且只在磁盘上有大约50-60mb的数据时写入磁盘。我会考虑这样做,因为现代硬盘驱动器可以写大约60MB的PR秒(这是一个台式硬盘驱动器,你的企业一次可以更快),不断写数据在小夹头是浪费IO带宽。

< P>我也有类似的情况,在我的例子中,我使用了一个带有LIFO同步对象的异步无锁队列 基本上,写入队列的线程在后进先出中设置同步对象,而其他线程的工作线程在后进先出中重置同步对象
我们有固定数量的同步对象,这些对象等于线程数。使用后进先出(LIFO)的原因是为了保持最少数量的线程运行并更好地使用缓存系统。

我想MSMQ在这方面不会有帮助,因为我们有这么多数据,MSMQ是某种高级API,即使它做得很少也会消耗CPU。在这种情况下,我们必须自己实现锁定机制。上面的代码似乎不是线程安全的。当您使用队列时,您根本不必担心线程安全。当您想获取队列中的元素时,只需退出队列。并且不会有跨线程的处理object@Bonshington事实并非如此。
队列
对象本身是共享的,它的内部状态不是线程安全的。谢谢你的想法。是的,我认为我们应该对数据进行缓冲并将其分块写入。丹尼尔,你认为我们可以使用.NET队列来实现这一目的吗?我们正在考虑使用ConcurrentQueue来存储指向数据的指针,但在开始记录之前,要为数据预先分配内存。您记录的是什么类型的数据?结构,简单字节,事实上,我的问题是数据是否可以在数据包中轻松序列化并按顺序读取。你在这里很低调,保持低调。
// another thread
protected void Loging(){
 while(true){
  while(myQ.Count > 0){
   var content = myQ.Dequeue();
   // save content
  }
  System.Threading.Thread.Sleep(1000);
 }
}