Parallel.Foreach被冻结但服务继续响应

时间:2016-10-05 16:16:47

标签: c# .net multithreading task-parallel-library

设计 我的C#WCF进程必须在内存中缓存大量数据(如字典) - 进程占用的内存增长超过1.5GB。 Cache中的数据或多或少来自数据库(使用实体框架)。构建缓存的方式是: 在表上选择查询以从表中获取主键列表(比如字符串列表)。假设我得到1000个项目的列表。 现在我在这个主键列表上执行Parallel.Foreach并且(foreach主体)操作是转到DB并获取该键的所有数据(即select * from table from KeyColumn = loop item)。对数据应用一些操作,然后将其添加到Cache(字典)中。

问题: 当进程/可执行文件启动时。它占用了近95%的CPU(这是好的)并占用RAM(比如说高达1.3或1.4 GB)。一直运行到最初的10-12分钟。但是,由于没有众所周知的原因,CPU的内存稳定在15-17%,稳定在1.4GB(还有更多)。我可以看到数据库中的几个项目尚未添加到缓存中。这种冻结状态持续很长时间(有时10小时),然后一切都会处理,所有数据都在我的缓存中。 RAM现在稳定在1.5GB左右。我认为GC循环会冻结应用程序线程,但随后(因为它是一个WCF服务)任何服务方法调用都会响应。它唯一的是并行线程部分,它似乎每次都冻结,每次重启都在相同的RAM大小。和数据明智的同一组项目每次从缓存中丢失。 我已经确认数据中没有任何不同之处,因为那些非常缺失的密钥。

寻找关于什么似乎是错误的指示?

修改

简单来说,我的代码流程如下:

ConcurrentDictionary<string, string> MyCache = new ConcurrentDictionary<string, string>();

private List<string> GetPrimaryKeysFromDB()
{
using(var ctx = new MyDBContext())
{
List<string> results = ctx.MyTable.Select(x=>x.PrimeColumn).ToList();
return results;
}
}

private void SomeMethod()
{
List<string> ListOfPrimeItems = GetPrimaryKeysFromDB();

Parallel.Foreach(ListOfPrimeItems, #MaxDopSetting#, k =>
  {
ProcessDataForKey(k);
  });
}

private void ProcessDataForKey(string key)
{
// Goto DB and fetch record for key
// Each column (Entity data member) will undergo some processing here
// some string manipulations
// Finally convert the new state of data to XML (serialize) and store in cache
MyCache[key] = TranslatedStateOfData;
}

1 个答案:

答案 0 :(得分:2)

编写此更新,以便其他人可以从中受益。在我的案例中,任务并行库是完美的。问题发生在我的一个数据处理步骤中。 我正在使用正则表达式,我的一个正则表达式遭受“Catastrophic Backtracking

我修复了正则表达式,它的工作速度非常快(几分钟之内)。谢谢大家的建议,即使我发布了错误的问题。感到愚蠢,错过了这样一个小错误。