我编写了一个应用程序,通过UDP记录来自嵌入式系统的跟踪数据。目前,我收到数据报并解析出可变长度记录并将它们存储在列表中。前端可以访问列表并显示数据(图形和文本列表等)。
我遇到的问题是有时我需要记录大量的数据。我的列表实现导致了内存不足异常。
我的要求是:
有没有人对如何攻击这个提出一些建议?以下是我的一些想法:
答案 0 :(得分:1)
本地数据库确实是处理这种情况的好方法 - 特别是因为查询可以帮助您调查日志。另外,你的UDP接收程序可能只是一个单独的线程,它会在数据库中发送信息(如果你的数据真的快节奏,你可以有两个缓冲区并在它们之间交替;将完整的缓冲区刷新到数据库,而另一个是填满)。这实际上取决于你的项目规模。
您可以随时使用第三个选项(立即存储到文件中),并使用单独的“日志调查”工具来读取该文件而不会遇到OOM异常。
答案 1 :(得分:0)
.NET 4具有无锁队列。您可以设置一个队列,其中一个线程将UDP组件中的内容添加到日志中,另一个线程正在使用这些日志并将它们放入文件或数据库中。
答案 2 :(得分:0)
我所拥有的是一个队列,我添加了我正在使用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();
答案 3 :(得分:0)
我正在使用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并不总是更改。