我想将一些现有代码转换为Parallel.Foreach,但我是这个多线程编程的新手,我试图修改代码,但它显示了一些意想不到的行为。每次出错都有。我已经了解了要实现的locking
机制,但我不知道如何以及在何处添加lock
语句。我也不确定OrganizationRequestCollection
是否是线程安全的。
public void ImportDataToCRM(List<Invoice> invoicesList, List<InvoiceLine> invoiceLinesList)
{
var organizationRequestCollection = new OrganizationRequestCollection();
foreach (Invoice invoice in invoicesList) //Need to convert this to Parallel.ForEach
{
Entity invoiceEntity = EntityMapper.GetEntity<Invoice>(invoice);
List<InvoiceLine> relatedLines = invoiceLinesList.Where(x => x.InternalId.Equals(invoice.InternalId) && x.DocumentNumber.Equals(invoice.DocumentNumber)).ToList();
if (relatedLines != null && relatedLines.Count > 0)
{
EntityCollection invoiceLineEntityCollection = new EntityCollection();
foreach (var invoiceLine in relatedLines ) //should this be converted to Parallel.Foreach??
{
Entity invoiceLineEntity = EntityMapper.GetEntity<InvoiceLine>(invoiceLine);
//Lock here ??
invoiceLineEntityCollection.Entities.Add(invoiceLineEntity);
}
//Lock here ??
invoiceEntity.RelatedEntities.Add(new Relationship("invoice_details"), invoiceLineEntityCollection);
}
//Lock here ??
organizationRequestCollection.Add(new CreateRequest()
{
Target = invoiceEntity
});
}
}
https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.organizationrequestcollection.aspx
https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.entitycollection.aspx
答案 0 :(得分:0)
1 - 分配到ToList()
List<InvoiceLine> relatedLines =
来电
第二 - 很难从代码中扣除,但是如果有可能的话
不同的Entity invoiceEntity = EntityMapper.GetEntity<Invoice>(invoice);
将返回相同的 invoiceEntity
,您肯定需要锁定invoiceEntity.RelatedEntities.Add(..)
。
另一方面,如果设计保证您的程序永远不会发生,请不要使用lock()
。
3 - 关于organizationRequestCollection
:它是假设并行的在之外的,但是 里面的到Add(..)
,所以,是的,使用此设计,您需要lock()
那里。