В моем случае, когда у меня был включен флаг оптимизации, он не завершил бы все операции, поэтому в конечном результате отсутствовали точки измерения, поэтому я просто отключил флаг оптимизации, чтобы исправить ошибку:
using System.Threading.Tasks;
Parallel.Invoke(
async () => await ProcessPartialArrayOperationAssets(operationAssets, 0, operationAssets.Count / 2,
operations, inspection1),
async () => await ProcessPartialArrayOperationAssets(operationAssets, operationAssets.Count / 2,
operationAssets.Count, operations, inspection1)
);
private async Task ProcessPartialArrayInspectionOperations(IList<InspectionOperation> operations,
int begin,
int end,
Inspection inspection,
InspectionAsset inspectionAsset)
{
await Task.Run(() =>
{
// create one new operation measuring point for each measuring point in the operation's equipment
int itemCounter = begin + 1;
for (int i = begin; i < end; i++)
{
lock (_thisLock)
{
InspectionOperation operation = operations[i];
int itemNumber = 1;
// get the asset
InspectionAsset operationAsset = operation.OperationAsset;
if (operationAsset != null)
{
// get the measuring points
string ABAPTrue = Abap.ABAP_TRUE;
lock (_thisLock)
{
IList<MeasuringPoint> measuringPoints = DbContext.MeasuringPoints.Where(x =>
x.AssetID == operationAsset.AssetID && x.InactiveFlag != ABAPTrue)
.ToList();
if (measuringPoints != null)
{
//Debug.WriteLine("measuringPoints.Count = " + measuringPoints.Count);
// create the operation measuring points
foreach (MeasuringPoint measuringPoint in measuringPoints)
{
OperationMeasuringPoint operationMeasuringPoint =
new OperationMeasuringPoint
{
InspectionID = inspection.InspectionID,
OperationNumber = operation.OperationNumber,
SubActivity = "",
RoutingNo = "",
ItemNumber = itemNumber.ToString("D4"),
// e.g. "0001", "0002" and so on
ItemCounter = itemCounter.ToString("D8"),
// e.g. "00000001", "00000002" and so on
MeasuringPointID = measuringPoint.MeasuringPointID,
MeasuringPointDescription = measuringPoint.Description,
Equipment = inspectionAsset.AssetID,
Category = "P"
};
DbContext.Entry(operationMeasuringPoint).State = EntityState.Added;
itemNumber++;
itemCounter++;
}
}
}
}
}
}
});
}
Таким образом, я заменил вызов Parallel.Invoke на этот.К вашему сведению, эта проблема возникла при использовании .NET Framework 4.7.
await ProcessPartialArrayOperationAssets(operationAssets, 0, operationAssets.Count, operations, inspection1);
ОБНОВЛЕНИЕ:
ОК, я обнаружил, что смог повторно включить оптимизациюпометьте и используйте Parallel.Invoke
, если я удаляю async Task
из сигнатуры метода:
private void ProcessPartialArrayInspectionOperations(IList<InspectionOperation> operations,
int begin,
int end,
Inspection inspection,
InspectionAsset inspectionAsset)
{
// create one new operation measuring point for each measuring point in the operation's equipment
int itemCounter = begin + 1;
for (int i = begin; i < end; i++)
{
InspectionOperation operation = operations[i];
int itemNumber = 1;
// get the asset
InspectionAsset operationAsset = operation.OperationAsset;
if (operationAsset != null)
{
// get the measuring points
string ABAPTrue = Abap.ABAP_TRUE;
lock (_thisLock)
{
IList<MeasuringPoint> measuringPoints = DbContext.MeasuringPoints.Where(x =>
x.AssetID == operationAsset.AssetID && x.InactiveFlag != ABAPTrue)
.ToList();
if (measuringPoints != null)
{
//Debug.WriteLine("measuringPoints.Count = " + measuringPoints.Count);
// create the operation measuring points
foreach (MeasuringPoint measuringPoint in measuringPoints)
{
OperationMeasuringPoint operationMeasuringPoint =
new OperationMeasuringPoint
{
InspectionID = inspection.InspectionID,
OperationNumber = operation.OperationNumber,
SubActivity = "",
RoutingNo = "",
ItemNumber = itemNumber.ToString("D4"),
// e.g. "0001", "0002" and so on
ItemCounter = itemCounter.ToString("D8"),
// e.g. "00000001", "00000002" and so on
MeasuringPointID = measuringPoint.MeasuringPointID,
MeasuringPointDescription = measuringPoint.Description,
Equipment = inspectionAsset.AssetID,
Category = "P"
};
DbContext.Entry(operationMeasuringPoint).State = EntityState.Added;
itemNumber++;
itemCounter++;
}
}
}
}
}
}
Parallel.Invoke(
() => ProcessPartialArrayInspectionOperations(operations, 0, operations.Count / 2,
inspection1, inspectionAsset),
() => ProcessPartialArrayInspectionOperations(operations, operations.Count / 2,
operations.Count, inspection1, inspectionAsset)
);
В качестве альтернативы, я думаю, я мог бы использовать Task.Run
для каждого, а затем ждать Task.WhenAll(t1, t2, t3);
, как объяснено здесь,но в этом случае я не делаю явных обращений к базе данных, поэтому я не думаю, что это применимо для использования Task.Run
вместо Parallel.Invoke
, хотя эта страница объясняет, почему мой Parallel.Invoke не завершал: Parallel.Invoke делаетне ждите завершения асинхронных методов
Подробнее см. в разделе «Параллелизм в C #» https://stephencleary.com/book/