2013-11-27 17 views
10

Sto affrontando qualche problema in parallel.foreach che è "L'indice era fuori dai limiti dell'array". Allego un codice per parallel.foreach e dove si blocca.Parallel.Foreach dando errore "L'indice era fuori dai limiti dell'array"

var lstFRItems = session.CreateCriteria<TFRItem>().Add(Restrictions.Eq("TSCEnterprise.FEnterpriseID", EnterpriseId)).AddOrder(Order.Asc("FName")).List<TFRItem>(); 
        List<FRItemAccount> lstItemAccount = new List<FRItemAccount>(); 
        var ListAccounts = session.CreateCriteria<TFRItemAccount>().List<TFRItemAccount>(); //lstFRItems.Select(i => new { i.TFRItemAccounts }).ToList(); 
        //foreach (var item in lstFRItems) 
       Parallel.ForEach(lstFRItems, item => 
       { 
        var lstItemAcc = ListAccounts.Where(i => i.TFRItem == item); //item.TFRItemAccounts.ToList(); 
        FRItemAccount account = new FRItemAccount(); 
        account.ItemID = item.FItemID; 
        account.ItemAccount = new List<ItemAccount>(); 
        // foreach (var itemAcct in lstItemAcc) 
        Parallel.ForEach(lstItemAcc, itemAcct => 
        { 
         ItemAccount oItemAccount = new ItemAccount(); 
         if (itemAcct != null) 
         { 
          oItemAccount.ItemAccountID = itemAcct.FItemAccountID; 

          if (itemAcct.TSCProperty == null) 
          { 
           oItemAccount.ForID = itemAcct.TSCCompany.FCompanyID; 
           oItemAccount.ForCompanyName = "Co# " + "- " + itemAcct.TSCCompany.FID + " " + itemAcct.TSCCompany.FName; 
           oItemAccount.FID = itemAcct.TSCCompany.FID; 
           oItemAccount.ForType = 1; 
          } 
          else 
          { 
           oItemAccount.ForID = itemAcct.TSCProperty.FPropertyID; 
           oItemAccount.ForCompanyName = "Prop# " + "- " + itemAcct.TSCProperty.FID + " " + itemAcct.TSCProperty.FName; 
           oItemAccount.FID = itemAcct.TSCProperty.FID; 
           oItemAccount.ForType = 2; 
          } 
          oItemAccount.Account = itemAcct.FAccount; 
          account.GLAccount = itemAcct.FAccount.ToString("#0.000"); //Formatted by Lhore Bansal 
          // account.Account = itemAcct.FAccount; 
          oItemAccount.isExisting = true; 
          //Original TFRItemAccount 
          oItemAccount.orgItemAccount = itemAcct; 
         } 
         if (lstItemAcc == null) 
          account.ItemID = item.FItemID; 
         account.ItemAccount.Add(oItemAccount); 
        }); 
        //Original tFRItem 
        account.Item = item; 
        //account.BaseAccount = Convert.ToDouble(item.FBaseAccount.ToString("F0")); // commented by jeet 
        account.BaseAccount = Convert.ToDouble((int)item.FBaseAccount); // added by jeet 
        account.Name = item.FName; 
        account.Type = item.FType; 
        lstItemAccount.Add(account); 
       }); 
        // tx.Commit(); 
        return Item = lstItemAccount; 

E si blocca al terzo ultima riga "lstItemAccount.Add (account)". Quando ho visto in lstItemAccount, ha alcuni conteggi e nella sezione di base ha un errore "base {System.SystemException} = {"Source array was not long enough. Check srcIndex and length, and the array's lower bounds."}".

Qual è la soluzione di questo errore?

+0

fyi - potresti avere un problema di threading con 'lstItemAccount'. –

+0

Hai trovato una risposta funzionante per questa domanda? –

risposta

8

ha a che fare con

ListAccounts.Where(i => i.TFRItem == item); 
account.ItemAccount.Add(oItemAccount); 
lstItemAccount.Add(account); 

liste e array non sono thread-safe. Utilizzare ConcurrentBag invece

22

Vorrei utilizzare uno ConcurrentBag<T> anziché List<T>. List<T> è progettato per l'accesso a un solo thread.

+0

Grazie..Daniel.It sta funzionando bene ora. –

+0

Questo dovrebbe essere contrassegnato come risposta. – garenyondem