Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编程c#:并行。Foreach内存消耗管理_C#_Entity Framework_Memory_Parallel Processing - Fatal编程技术网

编程c#:并行。Foreach内存消耗管理

编程c#:并行。Foreach内存消耗管理,c#,entity-framework,memory,parallel-processing,C#,Entity Framework,Memory,Parallel Processing,我想使用Parallel.Foreach机制来确保CPU在CPU密集型任务中的充分利用。我一次一个地从数据库中查询大量对象(每个迭代中只有一个对象,每个对象都相当小),然后在此对象上执行大量基于CPU的操作,然后将其保存回数据库 我在数据模型方面使用实体框架,并且给定我查询的对象数量,我为每次迭代创建一个新的上下文(这是为了限制内存消耗): 这在同步实现中效果很好,因为在每次迭代之后,都会处理从数据库查询的模型和实体框架上下文。因此,在这个过程中,我的内存消耗几乎是恒定的,这是非常大的。如果我不

我想使用Parallel.Foreach机制来确保CPU在CPU密集型任务中的充分利用。我一次一个地从数据库中查询大量对象(每个迭代中只有一个对象,每个对象都相当小),然后在此对象上执行大量基于CPU的操作,然后将其保存回数据库

我在数据模型方面使用实体框架,并且给定我查询的对象数量,我为每次迭代创建一个新的上下文(这是为了限制内存消耗):

这在同步实现中效果很好,因为在每次迭代之后,都会处理从数据库查询的模型和实体框架上下文。因此,在这个过程中,我的内存消耗几乎是恒定的,这是非常大的。如果我不以这种方式创建上下文,我很快就会耗尽内存(500多个对象)

当我以如下方式并行设置上述内容时,我的内存消耗量达到了极高的水平,因为似乎在下一次迭代继续之前没有处理每个迭代的上下文(我确实看到了预期的CPU利用率显著提高):


从内存的角度来看,这不一定是一个问题,只要所有模型对象不是一次加载到内存中(这实际上也是并行循环的整个点,一次加载多个)。但是,是否有某种方法可以更好地管理此过程,例如,当内存消耗达到(例如)75%时,不创建额外任务以避免内存不足异常?

TL;DR:您可以在下次操作之前使用MemoryFailPoint检查内存是否足够。微软文档有一个很好的例子


我最近也有类似的问题。我在检查旧应用程序的日志时注意到一些“内存不足异常”。事实证明,一位开发人员引入了一些并行编程来提高应用程序的速度。因此,也许应用程序速度更快,但它现在消耗内存的速度更快,达到2GB左右,然后出现内存不足异常。

看看这个:你可以调整一次可以运行的任务数量。CPU密集型工作的性质是什么?您是否排除了在数据库本身中执行所有这些活动?因此我尝试调整MaxDegreeOfParallelism选项,将其设置为1以进行测试。使用同步循环,我的内存消耗大致保持在600MB。然而,在并行结构中使用完全相同的循环时,内存仍然会增加到>1GB。因此,GC似乎没有正确地收集对象,或者并行构造没有正确地处理对象?密集工作的本质是使用合理的高级数学算法对计算进行建模,不会真正对SQL友好。可能还需要指出的是,我的内存消耗在并行循环之前从600MB开始,在循环执行期间上升到>1GB,然后在并行循环完成后保持在>1GB的水平(循环后的断点),而同步循环期间的内存消耗从600MB开始,并在循环期间和之后保持不变(随着每次迭代的完成和GC的收集,预期会有小的波动)。
    foreach (var id in idlist)
    {
        using (var ctx = new Context())
        {
            var model = ctx.Models.First(x => x.Id == id);
            await model.GlobalRefresh(true); //CPU heavy operation.
            await model.SaveAsync(); //Additional CPU heavy operation.
            ctx.SaveChanges(); //Save the changes
        } //Dispose of the model and the context, to limit memory consumption
    }
        Parallel.ForEach(idlist, async (id) =>
        {
            using (var ctx = new Context())
            {
                var model = ctx.Models.First(x => x.Id == id);
                await model.GlobalRefresh(true);
                await model.SaveAsync();
                ctx.SaveChanges();
            }
        });