定期更新EF中多个线程的实体

时间:2011-03-31 13:09:15

标签: c# .net multithreading entity-framework architecture

我有以下情况:

我有一个数据库,用于存储由服务器捕获和处理的作业。数据库通过实体框架访问。

服务器使用多个线程并行处理作业。为此我有一个线程,它定期检查数据库中的新作业并将它们分配给工作线程。

我现在的问题是我的实体有一个Progress属性,应该由工作线程更新并定期写入数据库。

工作线程经常更新属性(每秒多次),但是对于我的要求,如果数据库每隔几秒更新就足够了,我不想对数据库进行许多不必要的更新。

到目前为止,我的解决方案是让工作线程直接将进度写入实体,并让检查更新的线程也将这些更改发送到数据库。

我的问题是:从EF的角度来看,这个线程是否安全。我可以从一个线程更新实体的属性,并将更改写入另一个线程上的数据库吗?我是否需要锁定?请记住,我只在一个线程中使用DataContext(最少添加,因为我不知道在更新(非POCO)实体时内部EF的作用。

现在的另一个要求是我需要在工作进程中从数据库加载其他数据。我假设我必须为此使用单独的DataContexts,我真的不想在同一个线程中管理来自两个独立数据上下文的实体。

你有什么建议如何以一种很好的方式构建它?

由于每个worker只更新一个Job-Entity的状态,因此一个想法是将进度公开为worker-threads类中的属性,该类由主线程获取,然后主线程将更新实体并发布更新到数据库。但我仍然需要工作线程中的原始Job-Entity来读取配置数据,如果我将它重新连接到工作线程的DataContext,我就不能再在主线程中使用Entity了。如果不是真的有必要,我想避免加载同一个实体2次......

是否可以自动复制实体,在2个单独的DataContexts中使用它?

感谢您的任何想法!

2 个答案:

答案 0 :(得分:1)

最后我做出了以下决定:

我的主类/主线程从数据库中读取作业并将它们分发到各种工作线程。对于每个作业,都有一个相应的Job-Executor,其工作线程运行.Execute()方法。

按照惯例,Executor类在构造时从Job-Entity读取所有必要的配置数据,并且在执行期间不允许再触摸它。由于Executor类的构造是从主线程完成的,因此这里没有多线程访问。

更改状态,就像Job的进度一样,通过执行器类的属性公开,并定期从主线程同步到实体/数据库。

工作线程也有自己的DataContext,以便在必要时加载其他数据。

对DataContext的所有其他多线程访问都与锁同步。

答案 1 :(得分:0)

我认为你应该重新设计一下你的系统。

您遇到了麻烦,因为实体的进度存储在实体中。

如果您将其分开,以便您有一个包含所有作业进度的表/上下文。每个线程都可以更新它,并且可以使用计时器定期保存到数据库中。