[英]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.