繁体   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