[英]How to process a high speed stream of data that only requires the "last" value for a symbol in a database C#
[英]C# high speed data logging data handling
我编写了一个应用程序,通过UDP记录来自嵌入式系统的跟踪数据。 目前,我收到数据报并解析出可变长度记录并将它们存储在列表中。 前端可以访问列表并显示数据(图形和文本列表等)。
我遇到的问题是,有时我需要记录大量的数据。 我的列表实现导致了内存不足异常。
我的要求是:
有没有人对如何攻击这个有一些建议? 以下是我的一些想法:
本地数据库确实是处理这种情况的好方法 - 特别是因为查询可以帮助您调查日志。 另外,你的UDP接收程序可能只是一个单独的线程,它会在数据库中发送信息(如果你的数据真的快节奏,你可以有两个缓冲区并在它们之间交替;将完整的缓冲区刷新到数据库,而另一个是填满)。 这实际上取决于你的项目规模。
您可以随时使用第三个选项(立即存储到文件中),并使用单独的“日志调查”工具来读取该文件而不会遇到OOM异常。
.NET 4具有Lock free队列。 您可以设置一个队列,其中一个线程将UDP组件中的内容添加到日志中,另一个线程正在使用这些日志并将它们放入文件或数据库中。
我所拥有的是一个队列,我添加了我正在使用Log(字符串内容)方法登录的消息。 我有另一种方法,我在后台线程中开始,它不断读取队列并写入文件。 即使在太多数据通过之后可以完成写入,也会保留时间戳。
日志记录方法是静态的和公共的,因此可以从任何线程调用它。 我不能保证这个代码编译,因为我把它从我的项目中删除并删除了一些东西。
我发现由于我的计算机DISK I / O很糟糕,我没有收到超过1或2个线程写入的性能提升。 如果将日志记录拆分为多个文件,则可能会加快速度,但不能肯定地说。
private static StreamWriter sw;
private static Queue<string> logQueue = new Queue<string>();
public static string logLock = "";
public static void LogLoop()
{
sw = new StreamWriter("logFilePath.log"), true);
sw.AutoFlush = true;
while (true)
{
while (logQueue.Count > 0)
{
string s = "";
lock (logLock) // get a lock on the queue
{
s = logQueue.Dequeue();
}
sw.WriteLine(s);
}
Thread.Sleep(10);
}
}
public static void Log(string contents)
{
contents = DateTime.Now.ToString("MM-dd-yy - HH:mm:ss ffff") + " - " + contents; // add a timestamp
lock (logLock) // get a lock on the queue
{
logQueue.Enqueue(contents);
}
}
这就是我开始后台线程方法的方法。
Thread logThread = new Thread(LogLoop);
logThread.IsBackground = true;
logThread.Name = "Logging Thread";
logThread.Start();
我正在使用Josiah的方法来创建一个可重用的Logger类。 但是,我使用一个标志而不是while(true),允许循环在设置为false时终止。
while (logging) // instead of while(true)
{
while (logQueue.Count > 0)
{
string s = "";
lock (logLock)
{
s = logQueue.Dequeue();
}
write(s);
}
Thread.Sleep(timer);
}
它运行良好,但我发现在logQueue.Count值实际更改之前可以将数千条消息排入队列。
for (int i = 0; i <5000; i++)
{
lock (logLock)
{
logQueue.Enqueue(i.toString());
}
}
logging = false;
有时,上述代码会导致LogLoop在实际写入文件之前终止。 在将日志记录设置为false之前暂停,但是我仍然感到惊讶的是,在队列识别消息之前,logQueue.Count并不总是会发生变化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.