【问题标题】:Linq To Entities, ToList() exception when called from non-UI thread从非 UI 线程调用时,Linq To Entities,ToList() 异常
【发布时间】:2011-04-20 08:25:14
【问题描述】:

我使用的是 EF 4.0,它工作得非常好,但是出现了问题 我叫查询:


var query = from employee in employees from cr in employee.RcpCrossRegister select new { employee, cr } 然后当我打电话时

var list = query.ToList()

我遇到了异常

    Collection was modified; enumeration operation may not execute
and call stack: 

       w System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   w System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   w System.Collections.Generic.List`1.Enumerator.MoveNext()
   w System.Data.Objects.DataClasses.EntityCollection`1.CheckIfNavigationPropertyContainsEntity(IEntityWrapper wrapper)
   w System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget, Boolean applyConstraints, Boolean addRelationshipAsUnchanged, Boolean relationshipAlreadyExists, Boolean allowModifyingOtherEndOfRelationship, Boolean forceForeignKeyChanges)
   w System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedEntity, Boolean applyConstraints)
   w System.Data.Objects.DataClasses.EntityReference`1.set_ReferenceValue(IEntityWrapper value)
   w System.Data.Objects.DataClasses.EntityReference.SetEntityKey(EntityKey value, Boolean forceFixup)
   w System.Data.Objects.EntityEntry.FixupEntityReferenceToPrincipal(EntityReference relatedEnd, EntityKey foreignKey, Boolean setIsLoaded, Boolean replaceExistingRef)
   w System.Data.Objects.EntityEntry.FixupReferencesByForeignKeys(Boolean replaceAddedRefs)
   w System.Data.Objects.ObjectStateManager.FixupReferencesByForeignKeys(EntityEntry newEntry, Boolean replaceAddedRefs)
   w System.Data.Objects.ObjectStateManager.AddEntry(IEntityWrapper wrappedObject, EntityKey passedKey, EntitySet entitySet, String argumentName, Boolean isAdded)
   w System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
   w lambda_method(Closure , Shaper )
   w System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
   w System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
   w TCS.bos.Infrastructure.Data.MainModule.Repositories.EmployeeRepository.GetEmployeesEvacuationTimeSheet(Int64 dateHour)
   w TCS.bos.Domain.MainModule.Employees.EmployeeTimeSheetService.GetEmployeesEvacuationTimeSheet(Int64 dateHour)
   w TCS.plg.TimeSheets.ViewModels.TimeSheetsGridViewModel.GetAll2()
   w TCS.plg.TimeSheets.ViewModels.TimeSheetsGridViewModel.<>c__DisplayClass4.<FilterCommand>b__2()
   w TCS.Core.Caliburn.Invocation.BackgroundTask.<>c__DisplayClassd.<.ctor>b__4(Object s, DoWorkEventArgs e) w D:\VS2010\CaliburnMicro\caliburnmicro_a63379fba70a\TCS.2.3\TCS.Core\Caliburn\Invocation\BackgroundTask.cs:wiersz 41
   w System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
   w System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)

【问题讨论】:

  • 在创建查询和枚举查询之间你会做什么?它是延迟的,因此在您尝试枚举之前,您之前所做的任何事情都不会发生。
  • 你是对的,但这正是我使用的代码......

标签: entity-framework linq thread-safety linq-to-entities


【解决方案1】:

实体框架不是线程安全的,您只能在创建它的线程上使用ObjectContext

【讨论】:

  • ... 重要提示:此异常仅在从非 UI 线程调用时发生...我怀疑“关系修复”在收集方面做了一些工作,并导致异常但不知道如何修复它... ---------- 当我从 UI 线程调用它时我没有任何问题,但我需要在 UI 线程上显示进度条 ....
  • 它适用于 UI 线程,因为您可能在 UI 线程上创建了 ObjectContext...
  • @Thomas Levesque:“不是线程安全的”不等于“只能在创建它的线程上使用”。你能看出区别吗?
  • @zespri,是的,我知道区别,但为了简单起见,我没有在回答中提到它。无论如何,每次我试图从另一个线程而不是创建它的线程来操作 ObjectContext 时,我都会遇到类似的问题。
  • 当我调用简单查询“从员工中的员工选择员工”然后 ToList() 它工作正常,所以关于“关系修复”的理论似乎是正确的......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多