[英]How to make Parallel.ForEach split work into larger chunks?
我正在使用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");
原來相加Max Pool Size=24;Connection Timeout=60;
連接字符串的作用比嘗試重新划分列表要好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.