设计:
我的C#WCF进程必须在内存中缓存大量数据(如Dictionary)-进程占用的内存超过1.5GB。缓存中的数据或多或少来自数据库(使用 Entity Framework )。缓存的构建方式是:
在表上选择查询,以从表中获取主键列表(例如字符串列表)。假设我得到了1000个项目的 list 。
现在我在这个主键列表上执行Parallel.Foreach,并且(foreach的主体)操作将转到数据库并获取该键的所有数据(即从表中选择*,其中KeyColumn =循环项)对数据进行一些操作,然后将其添加到缓存(词典)中。
问题:
当进程/可执行文件启动时。它消耗了将近95%的CPU(这是很好的),并且占用了RAM(例如高达1.3或1.4 GB)。将运行良好,直到前10-12分钟。但是随后,由于未知原因,CPU的RAM降至15-17%,稳定在1.4GB(还有更多)。而且我可以看到数据库中有几项尚未添加到缓存中。这种冻结状态会持续很长时间(有时为10小时),然后一切都会处理,所有数据都在我的缓存中。 RAM现在稳定在1.5GB左右。我以为GC周期会冻结应用程序线程,但随后(由于它是WCF服务),任何Service方法调用都会响应。它唯一的并行线程部分似乎每次都冻结,每次重新启动时都具有相同的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;
}
最佳答案
编写此更新,以便其他人可以从中受益。就我而言,任务并行库是完美无缺的。问题出在我的数据处理步骤之一。
我正在使用正则表达式,而我的一个正则表达式遭受了“Catastrophic Backtracking”
我修复了Regex,它的工作速度非常快(几分钟之内)。即使我发布了错误的问题,也谢谢大家的建议。错过了这样的小虫子感到很傻。