我正在执行从DataTable获取列的简单操作。在线程环境中执行此操作后,我面临异常。但是,我添加了Monitors来保持对对象的检查。我仍然有例外。
异常:InvalidOperationException:集合已修改;枚举操作可能无法执行。
在线错误:项目= result.AsEnumerable()。AsParallel()。Select(y => y.Field(ExtractField))。ToList();
代码段:
private List<string> SomeMethod(string ExtractField)
{
List<string> Items = null;
if (Monitor.TryEnter(_locker, 100))
{
try
{
DataTable result = GetDataTable();
if (Monitor.TryEnter(_locker1, 100))
{
try
{
Items = result.AsEnumerable().AsParallel().Select(y => y.Field<string>(ExtractField)).ToList(); // ExtractFeild is the column Name
}
finally
{
Monitor.Exit(_locker1);
}
}
Items.RemoveAll(item => String.IsNullOrEmpty(item));
return Items;
}
finally
{
Monitor.Exit(_locker);
}
}
return Items;
}
详细的异常:
System.AggregateException
HResult=0x80131500
Message=One or more errors occurred.
Source=System.Core
StackTrace:
at System.Linq.Parallel.QueryTaskGroupState.QueryEnd(Boolean userInitiatedDispose)
at System.Linq.Parallel.DefaultMergeHelper`2.System.Linq.Parallel.IMergeHelper<TInputOutput>.Execute()
at System.Linq.Parallel.MergeExecutor`1.Execute[TKey](PartitionedStream`2 partitions, Boolean ignoreOutput, ParallelMergeOptions options, TaskScheduler taskScheduler, Boolean isOrdered, CancellationState cancellationState, Int32 queryId)
at System.Linq.Parallel.PartitionedStreamMerger`1.Receive[TKey](PartitionedStream`2 partitionedStream)
at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.ChildResultsRecipient.Receive[TKey](PartitionedStream`2 inputStream)
at System.Linq.Parallel.ScanQueryOperator`1.ScanEnumerableQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
at System.Linq.Parallel.UnaryQueryOperator`2.UnaryQueryOperatorResults.GivePartitionedStream(IPartitionedStreamRecipient`1 recipient)
at System.Linq.Parallel.QueryOperator`1.GetOpenedEnumerator(Nullable`1 mergeOptions, Boolean suppressOrder, Boolean forEffect, QuerySettings querySettings)
at System.Linq.Parallel.QueryOpeningEnumerator`1.OpenQuery()
at System.Linq.Parallel.QueryOpeningEnumerator`1.MoveNext()
at System.Linq.ParallelEnumerable.ToList[TSource](ParallelQuery`1 source)
请在这里帮助。
答案 0 :(得分:0)
您可以通过实现锁来阻止其他线程修改集合。这实际上将使方法同步。
private static object _lock = new object();
private List<string> SomeMethod(string ExtractField)
{
List<string> Items = null;
try
{
lock (_lock)
{
DataTable result = GetDataTable();
Items = result.AsEnumerable().AsParallel().Select(y => y.Field<string>(ExtractField)).ToList();
Items.RemoveAll(item => String.IsNullOrEmpty(item));
}
}
catch (Exception ex)
{
// ...
}
return Items;
}