簡體   English   中英

限制進程的CPU使用率

[英]Limit CPU usage of a process

我有一個服務運行,它定期檢查文件夾中的文件,然后處理它。 (讀取它,提取數據,將其存儲在sql中)

所以我在測試盒上運行它,預計需要更長的時間。 該文件有160萬行,它在6小時后仍在運行(然后我回家了)。

問題是它運行的盒子現在已經完全癱瘓了 - 遠程桌面超時了所以我甚至無法停止它來停止這個過程,或者附加一個調試器來看看有多遠等等。它堅固地使用90%+ CPU,以及所有其他正在運行的服務或應用程序

代碼是(從內存中,可能無法編譯):

List<ItemDTO> items = new List<ItemDTO>();
using (StreamReader sr = fileInfo.OpenText())
{
    while (!sr.EndOfFile)
    {
        string line = sr.ReadLine()
        try {
           string s = line.Substring(0,8);
           double y = Double.Parse(line.Substring(8,7));

           //If the item isnt already in the collection, add it.
           if (items.Find(delegate(ItemDTO i) { return (i.Item == s); }) == null)
               items.Add(new ItemDTO(s,y));
         }
         catch { /*Crash*/ }
    }
    return items;
}

- 所以我正在努力改進代碼(任何提示贊賞)。

但它仍然可能是一個緩慢的事情,這是好的,我沒有問題,它花了很長時間,只要它不殺死我的服務器。

所以我想要你的好人是:1)我的代碼是否可靠地未經優化? 2)我可以限制代碼塊可能使用的CPU數量嗎?

干杯全都

您可能最好將其設置為空閑優先級,而不是限制其CPU使用率,因此只有在沒有任何其他方法可以執行時才會運行。 其他人已經提到了優化的可能性,所以我不會嘗試進入那個部分。

  1. 在列表上執行查找是O(n)操作,這意味着當列表變長時,搜索項目需要更長的時間。 您可以考慮將項目放入.NET 4.0 / 3.5中的HashSet中,或者對早期版本的.NET使用Dictionary ,它可以像索引一樣,如果您需要列表中的項目來維護原始順序,您可以繼續放置它們在列表中,但使用HashSet / Dictionary進行檢查。

  2. 您還可以在BackgroundWorker線程中運行此代碼,這將有助於在進程運行時保持UI響應。

在列表中查找是O(n)。 如果文件有160萬行(即160萬個項目),那么你將反復走過一百多萬行的列表,這會浪費很多時間。

正如其他人所建議的那樣,如果你進行了大量的搜索,那么你需要一個更好的數據結構。 一個旨在加快搜索速度的設計。

如果使用.NET 3.5,則可以使用HashSet集合,該集合為搜索提供了分攤的O(1)。 或者字典集合使用的是.NET 2.0

接下來你要問自己,如果文件有160萬行,你有足夠的內存嗎? 如果你這樣做,那么在內存中解析文件比將其發送到數據庫以處理重復文件更快,但如果你沒有足夠的內存,那么你將進行分頁。 很多。 (這可能是現在發生的事情)。

正如其他人所說,修復數據結構。

現在,我的眼睛點擊這句話“定期檢查文件夾中的文件,然后對其進行處理。” 經常“定期”以及為什么處理可能沒有改變的文件?

您可能需要查看System.IO.FileSystemWatcher http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx

你不能用SqlBulkCopy類批量加載這個文件,然后在數據庫服務器上進行處理嗎?

在回答1)我將使用排序列表(如果有大量冗余數據)或哈希字典而不是常規字典來加速搜索。

這是另一篇文章 ,可以幫助您決定兩種方法。

對於問題2),我將線程優先級設置為低於正常值。 看到這里

你真的需要把所有數據保存在內存中嗎? 您可以將它存儲在數據庫中(如果您需要簡單且功能強大的東西使用Sqlite)並使用sql處理它。

  • HashSet的
  • 線程優先級較低
  • 某種SQL批量插入

我不是ac#程序員,但看着我認為的邏輯

  1. 您每次在循環中創建一個新的字符串對象。 如果我必須在java中執行它,而不是使用字符串對象,我會使用StringBuffer。

  2. 您的數據文件很大,所以我認為您應該有邏輯在每'n'個記錄后清除數據庫中的信息。 您需要額外的邏輯來記錄到目前為止已清除的記錄。 或者,由於您的邏輯僅捕獲第一行數據並忽略后續重復項,而不是使用Find方法,您只能嘗試插入數據並捕獲sql失敗。

  3. 處理邏輯應該在一個單獨的線程中,以保持系統的響應。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM