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

线程安全实体框架6
EN

Stack Overflow用户
提问于 2013-11-03 23:07:01
回答 1查看 10.1K关注 0票数 18

刚刚开始测试EF6和它的异步功能。当我意识到它们不是线程安全的时候,我很惊讶。我还以为这就是重点。

我已经有自己的基于Task的扩展方法好几年了,但我一直在等待EF让它们成为线程安全的方法。

至少我的基于任务的函数lock as不会相互干扰。EF6甚至没有走到那一步。但主要的问题是我的代码与他们的代码有相同之处。例如,尝试发出一个异步查询,然后在它完成之前,尝试访问一个导航属性(在同一上下文中预先加载的完全独立的实体上),这会触发延迟加载。这可以由UI触发,也可以由immediate函数之外的其他代码触发,或者由十几个其他场景触发。

据我所知。dbContext中仅有的两个共享(实体之间)可变资源是连接和更改跟踪(缓存)。如果我们可以在功能中添加这些锁定,那么我们就会有一个线程安全的上下文。

我们甚至可以分两个阶段来做。如果我们可以实现一个提供程序,锁定用于查询数据库的一个集中式功能。那么任何未被跟踪的查询-无论是通过返回非实体(匿名)对象还是通过调用AsNoTracking() -都将是线程安全的,并且即使另一个线程可能正在请求延迟加载的对象,使用异步函数进行调用也是安全的。

我们的可伸缩性不会比我们现在每个线程使用一个上下文更糟糕,甚至异步函数也不在表中,如果你试图跳过一个等待来引入一点并行性,或者在一个事件系统(如wpf)中工作,一旦等待的函数返回任务,就可能触发。

所以我的问题是。有没有人实现过这样的提供程序。或者会有人愿意和我一起工作吗?

EN

回答 1

Stack Overflow用户

发布于 2015-01-29 00:04:52

我认为你正面临着一个架构问题。您所描述的是一个UI直接使用EF对象的应用程序,它打破了“关注点分离”的范例。

就我而言,我在模型层上使用自定义线程安全缓存,让所有事情都发生在模型层上。我使用广为人知的AsyncLock在缓存上实现了线程安全。

DbContext对象,以及每个与EF CRUD相关的操作都有非常有限的生命周期。每个CRUD操作实例化它自己的DbContext,并将模型对象返回到缓存,然后,上下文被垃圾收集。我的应用程序使用缓存作为抽象层,而缓存使用EF作为DB抽象层。

例如,浏览对象的附加属性是通过在Model层上实现自定义方法来完成的,该方法将对象Id作为参数,并将相关对象的列表返回到缓存。UI询问Cache,然后Cache询问EF,然后一旦可用,对cache的调用将对象返回给UI。就这么简单。

EntityFramework不是设计成线程安全的,所以没有办法以多线程的方式使用它。(EF thread safety)

你必须构建一个可以通过多线程访问的模型层,而不是并行访问你的DbContext。而且您的模型可以对DB进行多个并行调用,但请记住,每个调用都必须实例化并保持其自身的DbContext。在每次调用结束时,必须释放相关的DbContext。

DbContext实例化速度非常快,唯一的缺点是网络延迟。这就是为什么内存缓存是一个好主意。

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

https://stackoverflow.com/questions/19754368

复制
相关文章

相似问题

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