3

我正在尝试运行具有 32 个线程的并行 foreach 循环。

这个 foreach 循环正在调用:

WorkflowInvoker.Invoke(new MyWorkflow(), myInputDictionary)

并行 foreach 循环由大约 65000 个项目的列表组成。

在某些时候,在大约 6000 - 6700 个项目处,调用 WorkflowInvoker.Invoke(new MyWorkflow(), myInputDictionary) 会引发 AccessViolationException 并显示以下消息:“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”

我尝试了不同的方法,例如创建 WorkflowInvoker 的实例并将 MyWorkflow 的实例直接传递给新创建的 WorkflowInvoker,然后在类上调用 Invoke 方法。也只是将 WorkflowInvoker.Invoke 作为静态方法调用,但这并没有什么不同。应用程序每次都在同一点崩溃。由于线程的原因,很难调试和查明导致问题的确切原因。

当然,如果我在正常的 foreach 循环中进行调用,则不会出现问题。

起初我们认为虚拟机内存不足,因为应用程序开始消耗所有可用内存,直到达到总内存 (4GB) 的 85% 的限制,然后它似乎崩溃了。所以我们将内存大小更改为 1GB,看看我们是否可以在循环的早期引发异常,但是 Windows 开始进行垃圾收集,所以最后异常仍然发生在大约 6000 - 6700 个项目的同一点。

非常感谢任何关于我下一步应该采取什么行动的建议;-)

-- 编辑 - 添加了完整的堆栈跟踪 --

at System.Reflection.Emit.ModuleBuilder.nCreateISymWriterForDynamicModule(Module module, String filename)
at System.Reflection.Emit.AssemblyBuilder.DefineDynamicModuleInternalNoLock(String name, Boolean emitSymbolInfo, StackCrawlMark& stackMark)
at System.Reflection.Emit.AssemblyBuilder.DefineDynamicModuleInternal(String name, Boolean emitSymbolInfo, StackCrawlMark& stackMark)
at System.Reflection.Emit.AssemblyBuilder.DefineDynamicModule(String name, Boolean emitSymbolInfo)
at System.Activities.Debugger.StateManager.InitDynamicModule(String asmName)
at System.Activities.Debugger.StateManager..ctor(Properties properties, Boolean debugStartedAtRoot)
at System.Activities.Debugger.DebugManager..ctor(Activity root, String moduleNamePrefix, String typeNamePrefix, String auxiliaryThreadName, Boolean breakOnStartup, WorkflowInstance host, Boolean debugStartedAtRoot)
at System.Activities.Debugger.DebugController.EnsureActivityInstrumented(ActivityInstance instance, Boolean primeCurrentInstance)
at System.Activities.Debugger.DebugController.ActivityStarted(ActivityInstance activityInstance)
at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)
at System.Activities.Runtime.ActivityExecutor.ExecuteRootWorkItem.Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)
at System.Activities.Runtime.ActivityExecutor.OnExecuteWorkItem(WorkItem workItem)
at System.Activities.Runtime.Scheduler.Callbacks.ExecuteWorkItem(WorkItem workItem)
at System.Activities.Runtime.Scheduler.OnScheduledWork(Object state)
at System.Runtime.Fx.SendOrPostThunk.UnhandledExceptionFrame(Object state)
at System.Activities.WorkflowApplication.PumpBasedSynchronizationContext.WorkItem.Invoke()
at System.Activities.WorkflowApplication.PumpBasedSynchronizationContext.DoPump()
at System.Activities.WorkflowApplication.Invoke(Activity activity, IDictionary`2 inputs, WorkflowInstanceExtensionManager extensions, TimeSpan timeout)
at System.Activities.WorkflowInvoker.Invoke(Activity workflow, IDictionary`2 inputs, TimeSpan timeout, WorkflowInstanceExtensionManager extensions)
at System.Activities.WorkflowInvoker.Invoke(IDictionary`2 inputs)

-- 额外的编辑 - 添加了有问题的方法 - 对其进行了一些混淆以删除业务逻辑名称 -

public MyOutputData InvokeMyWorkflow(MyInputData input) 
{
      IDictionary<string, object> wfInput = new Dictionary<string, object>
       {
        { "ArgData", input }
       };
  MyWorkflow myWorkflow = new MyWorkflow();
  try
  {
       WorkflowInvoker invoker = new WorkflowInvoker(myWorkflow);
       IDictionary<string, object> output = invoker.Invoke(wfInput);
       return output["ArgData"] == null ? null : (MyOutputData)output["ArgData"];
  }
  catch (Exception ace)
  {
           Log.Error(ace.StackTrace);
       return null;
  }
 }
4

0 回答 0