首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架5线程敏捷

实体框架5线程敏捷
EN

Stack Overflow用户
提问于 2014-04-09 20:21:05
回答 1查看 707关注 0票数 3

在NullReferenceException代码中抛出一个EntityFramework代码(EF?),但我的问题是实体框架(v5)和WebAPI异步控制器操作。

在这里很难重新创建一个repro,但是代码本质上是这样做的:

代码语言:javascript
复制
public class AController : ApiController
{
    private IUow _uow; //among other things, a DbContext 
    // DI ctor
    public AController(IUow uow)
    {
        _uow = uow; 
    }

    [HttpPost]
    public async Task<HttpResponseMessage> Post(Model model)
    {
        Entity e = _uow.Entity.GetById(model.id);
        await IO_Ops_Async(model); 
        new ModelAdapter().UpdateEntity(entity, model);
        _uow.Commit(); <- EXCEPTION THROWN DURING THIS CALL - see below
        ... // do something with the return result
    }
}

Commit()内部,就在DbContext.SaveChanges()之前,我们循环遍历所有DbChangeTracker.Entries()来设置一些公共属性。但是,是Entries()在单个循环之前发生错误,NullReferenceExceptionSystem.Data.Entity.Infrastructure.DbChangeTracker.Entries()中很深。

下面是调用堆栈。这都是框架代码,感觉就像一个bug,但我的问题是,上面的异步/等待是否允许在DbContext调用之间使用。在任何时候,我们只使用多线程异步/等待,因为我们可以使用异步/等待工具执行一些IO操作(几个Httpclient下载+一些异步磁盘I/O)。

代码语言:javascript
复制
System.NullReferenceException: Object reference not set to an instance of an object.\r\n   
at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)\r\n   
at System.Data.Objects.DataClasses.EntityReference`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)\r\n   
at System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)\r\n   
at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)\r\n   
at System.Data.Objects.DataClasses.EntityCollection`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)\r\n   
at System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)\r\n   
at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)\r\n   
at System.Data.Objects.DataClasses.EntityReference`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)\r\n   
at System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)\r\n   
at System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget, Boolean applyConstraints, Boolean addRelationshipAsUnchanged, Boolean relationshipAlreadyExists, Boolean allowModifyingOtherEndOfRelationship, Boolean forceForeignKeyChanges)\r\n   
at System.Data.Objects.ObjectStateManager.PerformAdd(IEntityWrapper wrappedOwner, RelatedEnd relatedEnd, IEntityWrapper entityToAdd, Boolean isForeignKeyChange)\r\n   
at System.Data.Objects.ObjectStateManager.PerformAdd(IList`1 entries)\r\n   
at System.Data.Objects.ObjectStateManager.DetectChanges()\r\n   
at System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate)\r\n   
at System.Data.Entity.Infrastructure.DbChangeTracker.Entries()\r\n
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-09 20:34:51

await之后有一个由IO完成引起的隐式线程切换。AFAIK,EF5可能无法处理这一点,因为它使用线程本地存储。

OTOH、EF6.x (特别是最新的版本)在这种情况下应该可以正常工作。

相关:如何在ASP.NET Web中使用非线程安全的异步/等待API和模式?

更新了以回应这一评论:

因为异步/等待基础设施应该注意并流ExecutionContext (线程-本地存储和其他“上下文”)。我这样做是为了使我能够进行有教养的更改,并保留异步/等待实现,同时处理任何破坏EF的特定事情。

EF5源代码不是开源的(与EF6不同),所以我不能100%确定,但我怀疑EF5显式地使用了TLS (即ThreadStaticThreadLocal<T>)。automatically ExecutionContext**.**不可能将的所有 TLS属性都转换为,这将是对现有代码的巨大破坏和安全威胁(更不用说它在技术上甚至不可能实现这一点)。

ExecutionContext捕获并流线程属性的一个非常特定的子集。这个子集是没有文档的,但是您可以了解更多关于它的这里

它是特定类实现的一个负责任的,它的静态属性在多个线程之间流动,它有CallContext.LogicalSetData/CallContext.LogicalGetData。我相信这就是EF6在引擎盖下所做的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22973162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档