Rab*_*bbi 18 multithreading entity-framework task-parallel-library entity-framework-6
刚刚开始测试EF6及其异步功能.当我意识到他们不是线程安全时,男孩感到很惊讶.我有点认为那就是重点.
我已经有了Task多年自己的扩展方法,但是我在EF等待的是让它们保持线程安全.
至少我的基于任务的功能被lock编辑为不互相干扰.EF6甚至没有那么远.但主要问题是我的代码与他们的代码共享.即尝试发出异步查询,然后在它完成之前尝试访问导航延迟加载的导航属性(在同一上下文中预先加载的完全独立的实体上).这可以由UI或直接功能之外的其他代码触发,也可以由十几个其他场景触发.
据我所知.dbContext中仅有的两个共享(实体之间)可变资源是连接和更改跟踪(缓存).如果我们可以在功能性上添加锁定,那么我们就会有一个线程安全的上下文.
我们甚至可以分两个阶段完成.如果我们可以实现一个锁定用于查询数据库的集中函数的提供程序.然后任何非跟踪查询 - 通过返回非实体(匿名)对象或通过调用AsNoTracking() - 将是线程安全的,并且即使另一个线程可能要求延迟加载的对象,使用异步函数调用也是安全的.
我们的可扩展性不会更糟,我们现在必须使用每个线程一个上下文,如果你试图跳过一个等待引入一些并行性或者正在工作的事情,甚至Async函数都不在桌面上系统(如wpf)可能会在等待的函数返回任务时触发.
所以我的问题是.有没有人实现这样的提供者.或者有人愿意和我一起工作吗?
rdu*_*com 10
我认为你正面临一个建筑问题.您所描述的是UI直接使用EF对象的应用程序,它打破了"关注点分离"范例.
在我这边,我在Model层上使用了海关线程安全缓存,让一切都在Model层上发生.我使用众所周知的AsyncLock在我的缓存上实现了线程安全性.
DbContext对象和每个与EF CRUD相关的操作的生命周期非常有限.每个CRUD操作都实例化它自己的DbContext,并将模型对象返回到缓存,然后,上下文被垃圾收集.我的应用程序使用缓存作为抽象层,缓存使用EF作为DB抽象层.
例如,在Objects上探索附加属性是通过在Model层上实现自定义方法来完成的,该方法将对象Id作为参数,并将相关对象的列表返回到缓存.UI询问缓存,然后缓存询问EF,然后一旦可用,对缓存的调用将对象返回到UI.就那么简单.
EntityFramework的设计不是线程安全的,因此无法以多线程方式使用它.(EF线程安全)
您不必对DbContext进行并行访问,而是必须构建一个可以多线程方式访问的Model层.并且您的模型可以对您的DB进行多个并行调用,但请记住,每个调用必须实例化并保留它自己的DbContext.在每次调用结束时,必须处理相关的DbContext.
DbContext实际上很快实例化,唯一的缺点是网络延迟.这就是内存缓存是个好主意的原因.
| 归档时间: |
|
| 查看次数: |
9496 次 |
| 最近记录: |