【问题标题】:Periodically update entities from multiple threads in EF定期从 EF 中的多个线程更新实体
【发布时间】:2011-04-03 22:46:28
【问题描述】:

我有以下场景:

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

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

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

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

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

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

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

您对如何以一种好的方式构建它有什么建议吗?

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

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

感谢您的任何想法!

【问题讨论】:

  • 如果您不了解线程,那么您真的会给您自己和您的软件用户带来很多麻烦。使用线程有很多方法可以做到这一点,有些方法比其他方法更容易理解。我只是提醒你不要用这样一个高层次的话题来回答你自己的问题。您应该显示一些代码并来回显示一个小对话框,以便为您的问题找到正确的解决方案。

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


【解决方案1】:

最后我做了以下决定:

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

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

不断变化的状态,例如 Job 的进度,通过 executor 类上的属性公开,并定期从主线程同步到实体/数据库。

工作线程也有自己的 DataContext 来在必要时加载额外的数据。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 你能详细说明一下吗?我真的不明白这如何解决问题。如果每个线程都更新新的“进度”实体并且主线程定期保存它,这与我目前的设计基本相同,只是我有一个单独的表(每次查询作业时都必须包含它,等)...
    猜你喜欢
    • 2021-09-21
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多