【问题标题】:How to make Parallel.ForEach split work into larger chunks?如何使 Parallel.ForEach 拆分成更大的块?
【发布时间】:2017-04-26 16:52:47
【问题描述】:

我正在使用 Parallel.ForEach 在 Oracle DB 上执行一些工作,我从日志中看到它没有将负载分成 N 个块,其中 N = MaxDegreeOfParallelism。这是意料之中的,因为每个块可能需要更长或更短的时间来处理,但是块确实将工作负载分成太小。如果池处于启用状态 (ORA-12518),ODP.NET 会由于某种原因使打开连接的数据库过载,所以我禁用了它。这消除了错误,但我想减少打开和关闭连接所花费的时间。

有没有办法影响Parallel.ForEach 将工作负载分成更大的块?

作为参考,这是代码当前的样子:

//conn is the primary connection stored in the object

logger.Report("Started");

var allObjects = GetObjects(); //uses the primary connection
logger.Report(string.Format("Retrieved {0} objects", allObjects.Count));

var i = allObjects.Count;
var taskID = 0;

Parallel.ForEach(
    allObjects,
    new ParallelOptions { MaxDegreeOfParallelism = 16,  },
    () => {
        var c = (DbConnection)((ICloneable)conn).Clone();
        c.Open();
        var t = Interlocked.Increment(ref taskID);
        logger.Report(string.Format("Task #{0} started", t));
        return (conn: c, task: t);
    },
    (o, loopState, c) => {
        try {
            var objectName = o.Name;
            var objectType = o.Type;

            logger.Report(string.Format("Retrieving {0} {1}", objectType, objectName));
            var dbObject = GetObject(c.conn, o.Name, o.Type);

            logger.Report(string.Format("Processing {0} {1}", objectType, objectName));
            var result = ProcessObject(dbObject);

            logger.Report(string.Format("Recompiling {0} {1}", objectType, objectName));
            ProcessResult(c.conn, result);

            logger.Report(string.Format("{0} objects remaining", Interlocked.Decrement(ref i)));

            return c;
        } catch (Exception ex) {
            logger.Report("ERROR: " + ex);
            throw;
        }
    },
    c => {
        logger.Report(string.Format("Task #{0} finished", c.task));
        c.conn.Close();
        c.conn.Dispose();
    });

logger.Report("Recompiling invalids...");
RecompileInvalids(); //uses the primary connection

logger.Report("Done");

【问题讨论】:

标签: c# oracle parallel-processing task-parallel-library


【解决方案1】:

事实证明,将Max Pool Size=24;Connection Timeout=60; 添加到连接字符串比尝试重新分区列表效果更好。

【讨论】:

    猜你喜欢
    • 2020-05-06
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 2011-10-26
    • 2012-04-27
    • 2017-08-25
    相关资源
    最近更新 更多