Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 查询并行foreach结果导致空引用错误_C#_Parallel.foreach - Fatal编程技术网

C# 查询并行foreach结果导致空引用错误

C# 查询并行foreach结果导致空引用错误,c#,parallel.foreach,C#,Parallel.foreach,我有一个类似的foreach语句,如下所示 Parallel.ForEach(spacialRecords, (spacerecord) => { List<MeterValue> dat = new List<MeterValue>(); var latitude = Geometry.Y;

我有一个类似的foreach语句,如下所示

  Parallel.ForEach(spacialRecords, (spacerecord) =>
                   {
                       List<MeterValue> dat = new List<MeterValue>();
                       var latitude = Geometry.Y;
                       var longitude = spacerecord.Geometry.X;
                       var timeStamp = spacerecord.Timestamp;

                       foreach (var wdItem in workingData)
                       {
                           RepresentationValue spaceMeteredValue = spacerecord.GetMeterValue(wdItem);
                           if (spaceMeteredValue != null && wdItem.Representation != null)
                           {
                               var objMeterValue = new MeterValue();
                               objMeterValue.key = wdItem.Representation.Code;
                               objMeterValue.value = spaceMeteredValue.Designator != null ? Convert.ToString(spaceMeteredValue.Designator) : "";
                               dat.Add(objMeterValue);
                           }
                       }

                       listSpacialRecords.Add(new
                       {

                           operationLogDataId = yieldMaster.OperationalLogDataModelResponse.Id,
                           order = deviceElement.Order,
                           totalDistanceTravelled = deviceElement.TotalDistanceTravelled,
                           totalElapsedTime = deviceElement.TotalElapsedTime,
                           uploadedOn = DateTime.Now.ToUniversalTime(),
                           collectedOn = timeStamp.ToUniversalTime(),
                           cropId = "8296e610-c055-11e7-851e-ad7650a5f99c",
                           productId = productid,
                           latitude = latitude,
                           longitude = longitude,
                           deviceConfigurationId = deviceElement.DeviceConfigurationId,
                           operationDataId = deviceElement.OperationDataId,
                           spatialRecords = dat,
                           depth = depth,
                           timeStamp = timeStamp,
                           totaldata = totalRecordCount

                       });

                   });
代码在foreach循环之外。当我执行这个时,我得到了如下错误

Cannot perform run time binding on a null reference
但是当我删除并行并使用普通的foreach循环时,代码工作得很好

注意:我在上面做了一个断点,我发现listSpacialRecords正确地显示了所有记录,我已经用quickwatch检查过,直到最后一个元素数据可用,但仍然失败

有谁能帮我弄清楚我对这个问题的看法吗

listSpacialRecords.Add(...);
我假设这个方法不是显式的线程安全的(默认情况下不会)。所有线程都在与相同的
listSpacialRecords
对话

当您在
Parallel.ForEach
中执行此操作时,您将面临一场非常危险的线程竞争-如果两个线程同时调用
.Add
,那么可能会发生很多不好的事情-包括数据丢失

因此:同步所有对此
添加的调用。这可以是一个简单的方法,如:

var newValue = new {
    operationLogDataId = yieldMaster.OperationalLogDataModelResponse.Id,
    // etc etc...
};                           .
lock(listSpacialRecords) {
    listSpacialRecords.Add(newValue);
}

还有一个
dat.Add
,但是这个
dat
是上下文绑定到每个调用的,所以不需要同步。

当然,让我试试这个很酷的方法,它可以完美地工作。还有一个疑问,你能告诉我表演的情况吗?我有大量的数据,这就是为什么我使用并行foreach。那么锁定机制是否存在任何性能问题??因为我在这里得到并行的好处吗?@ArunprasanthKV如果你有很多数据,我担心首先把它们放在列表中可能是个坏主意;还要注意,这可能会改变顺序,因此如果顺序很重要:
Parallel.ForEach
是个坏主意<代码>并行。For
可能更好(因此在
i
的第次迭代中,您从位置
i
读取并写入某个数组中的位置
i
,甚至不需要锁定)。至于性能:代码中有一个额外的循环将主导操作,因此关于
锁的冲突将非常罕见(但非常有害)-基本上不会对性能产生任何影响
var newValue = new {
    operationLogDataId = yieldMaster.OperationalLogDataModelResponse.Id,
    // etc etc...
};                           .
lock(listSpacialRecords) {
    listSpacialRecords.Add(newValue);
}