2017-04-26 13 views
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"); 
+1

看一看這個答案:http://stackoverflow.com/a/16427390/1291717 –

+0

@SergeySlepov感謝,看起來像我將不得不實現自己的分區 – Alexey

+0

@Alexey你不」需要實現自己的。只需[指定塊大小](http://stackoverflow.com/a/43400778/213550) – VMAtm

回答

0

原來增加Max Pool Size=24;Connection Timeout=60;連接字符串的工作不是試圖重新分區列表更好。