0
我使用Parallel.ForEach
在Oracle數據庫上執行一些工作,我從日誌中看到它不會將負載分爲N個塊,其中N = MaxDegreeOfParallelism
。這是預料之中的,因爲每個塊可能需要更長或更短的時間才能處理,但是這些塊將工作負載分割得太小。由於某種原因,ODP.NET會因打開連接而打開數據庫(ORA-12518),從而導致數據庫超載,因此我將其禁用。這擺脫了錯誤,但我想減少打開和關閉連接的時間。如何將Parallel.ForEach拆分成更大的塊?
有沒有辦法影響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");
看一看這個答案:http://stackoverflow.com/a/16427390/1291717 –
@SergeySlepov感謝,看起來像我將不得不實現自己的分區 – Alexey
@Alexey你不」需要實現自己的。只需[指定塊大小](http://stackoverflow.com/a/43400778/213550) – VMAtm