我有一个 foreach 循环,里面有 Linq 查询。
在我将 foreach 更改为 Parallel.ForEach 之前,一切都运行良好:
// get the task info ---------
Log("Populate task, guf code lists ...........................");
List<SF_CO_ITEM> tasks = (from coi in ctx.SF_CO_ITEM
where coi.CO == co.ID
select coi).ToList();
// foreach (SF_CO_ITEM t in tasks)
// {
Parallel.ForEach(tasks, t =>
{
Log("Executing on t: " + t.ID);
// exception on next line:
List<SF_CO_LINE_ITEM> gufs = (from coli in ctx.SF_CO_LINE_ITEM
where coli.CO_ITEM == t.ID
select coli).ToList();
我得到的例外是:
System.AccessViolationException 未处理 Message=尝试读取或写入受保护的内存。这通常表明其他内存已损坏。Source=Oracle.DataAccess StackTrace:在 Oracle.DataAccess.Client.ConnectionDispenser.Open(OpoConCtx opoConCtx) 的 Oracle.DataAccess.Client.ConnectionDispenser.Open(IntPtr& opsConCtx, IntPtr& opsErrCtx, OpoConValCtx* pOpoConValCtx, OpoConRefCtx& pOpoConRefCtx) 处。 System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf 处的 Client.OracleConnection.Open()(布尔 openCondition,DbConnection storeConnectionToOpen,DbConnection originalConnection,字符串异常代码,字符串尝试操作,布尔和 closeStoreConnectionOnFailure)在 System.Data.EntityClient.EntityConnection.Open() 处。数据。
1.GetResults(Nullable
1 forMergeOption) 在 System.Data.Objects.ObjectQuery1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Collections.Generic.List
1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 源) 在 ChangeOrder.Program.<>c_ DisplayClass19.b _16(SF_CHANGE_ORDER_ITEM t) 在 C:\VS_apps\PMConsole\PMC Tools\ChangeOrderExecution\Program .cs:System.Threading.Tasks.Parallel.<>c_DisplayClass2d 处的 220 行1.b2.<ForEachWorker>b__23(Int32 i) at System.Threading.Tasks.Parallel.<>c__DisplayClassf
_c () 处 System.Threading.Tasks.Task.InnerInvoke() 处 System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)在 System.Threading.Tasks.Task.<> c_DisplayClass7.b_6(Object ) 在 System.Threading.Tasks.Task.ExecuteSelfReplicating(Task root) 在 System.Threading.Tasks.Task.Execute() 在 System.Threading.Tasks.Task.ExecutionContextCallback(Object obj) 在 System.Threading.ExecutionContext .Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 在 System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution) 在 System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot) 在 System.Threading.Tasks。 System.Threading.Tasks.TaskScheduler.TryRunInline(Task task, Boolean taskWasPrevouslyQueued, Object threadStatics) 在 System.Threading.Tasks.Task 的 ThreadPoolTaskScheduler.TryExecuteTaskInline(Task task, Boolean taskWasPreviousQueued)。InternalRunSynchronously(TaskScheduler scheduler) at System.Threading.Tasks.Task.RunSynchronously(TaskScheduler scheduler) at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action1 body, Action
2 bodyWithState,Func4 bodyWithLocal, Func
1 localInit,Action1 localFinally) at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IList
1 列表,ParallelOptions parallelOptions,Action1 body, Action
2 bodyWithState,Action3 bodyWithStateAndIndex, Func
4 bodyWithStateAndLocal,Func5 bodyWithEverything, Func
1 localInit,Action1 localFinally) at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IEnumerable
1 source,ParallelOptions,Action1 body, Action
2 bodyWithState,Action3 bodyWithStateAndIndex, Func
4 bodyWithStateAndLocal,Func5 bodyWithEverything, Func
1 localInit,Action1 localFinally) at System.Threading.Tasks.Parallel.ForEach[TSource](IEnumerable
1 来源,Action`1 body) 在 ChangeOrder.Program.PerformChangeOrder(SF_CHANGE_ORDER co, SF_CLIENT_PROJECT cp, SFEntitiesQA ctx) 在 C:\VS_apps\PMConsole\PMC Tools\ChangeOrderExecution\Program.cs:line 216 at ChangeOrder.Program.Main( C:\VS_apps\PMConsole\PMC Tools\ChangeOrderExecution\Program.cs 中的 String[] args):System.AppDomain._nExecuteAssembly 的第 1373 行(RuntimeAssembly 程序集,String[] args)在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,Evidence assemblySecurity, String[] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state,Boolean ignoreSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ThreadHelper.ThreadStart() InnerException:
我不确定我需要锁定什么,因为我只是在获取信息(只是 RO,对吗?)。
我考虑过添加“AsParallel”,但我的理解是这是一个 PLINQ 指令,它只会导致查询相对于自身并行运行。
我找不到任何人在 Parallel.ForEach 循环中运行 Linq 查询的例子,所以我什至不确定我在做什么是允许的。