相关疑难解决方法(0)

如果使用具有大对象的枚举,Parallel.ForEach可能会导致"内存不足"异常

我正在尝试将数据库中存储图像的数据库迁移到指向硬盘驱动器上的文件的数据库中的记录.我试图使用此方法来查询数据Parallel.ForEach以加快进程.

但是,我注意到我得到了一个OutOfMemory例外.我知道Parallel.ForEach会查询一批枚举,以减少开销的成本,如果有一个用于间隔查询(如果您一次执行一堆查询而不是间隔它们,您的源将更有可能将下一条记录缓存在内存中)出).问题是由于我返回的记录之一是1-4Mb字节数组,缓存导致整个地址空间用完(程序必须在x86模式下运行,因为目标平台将是32位机)

是否有任何方法可以禁用缓存或使TPL更小?


这是一个显示问题的示例程序.这必须在x86模式下编译,以显示问题,如果它在你的机器上花费很长时间或者没有发生,从而增加了阵列的大小(我发现1 << 20我的机器上大约需要30秒,4 << 20几乎是瞬间的)

class Program
{

    static void Main(string[] args)
    {
        Parallel.ForEach(CreateData(), (data) =>
            {
                data[0] = 1;
            });
    }

    static IEnumerable<byte[]> CreateData()
    {
        while (true)
        {
            yield return new byte[1 << 20]; //1Mb array
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c# out-of-memory large-data task-parallel-library

63
推荐指数
3
解决办法
3万
查看次数

为什么Parallel.ForEach比AsParallel()快得多.ForAll()即使MSDN建议不然?

我一直在做一些调查,看看我们如何创建一个贯穿树的多线程应用程序.

为了找到如何以最佳方式实现这一点,我创建了一个运行在我的C:\ disk中的测试应用程序并打开所有目录.

class Program
{
    static void Main(string[] args)
    {
        //var startDirectory = @"C:\The folder\RecursiveFolder";
        var startDirectory = @"C:\";

        var w = Stopwatch.StartNew();

        ThisIsARecursiveFunction(startDirectory);

        Console.WriteLine("Elapsed seconds: " + w.Elapsed.TotalSeconds);

        Console.ReadKey();
    }

    public static void ThisIsARecursiveFunction(String currentDirectory)
    {
        var lastBit = Path.GetFileName(currentDirectory);
        var depth = currentDirectory.Count(t => t == '\\');
        //Console.WriteLine(depth + ": " + currentDirectory);

        try
        {
            var children = Directory.GetDirectories(currentDirectory);

            //Edit this mode to switch what way of parallelization it should use
            int mode = 3;

            switch (mode) …
Run Code Online (Sandbox Code Playgroud)

c# parallel-processing performance foreach multithreading

32
推荐指数
2
解决办法
1万
查看次数