【问题标题】:Alternative To Passing A DbContext object To Parallel Task将 DbContext 对象传递给并行任务的替代方法
【发布时间】:2018-01-04 16:11:33
【问题描述】:

我有一个场景涉及对电子邮件列表执行相同的处理操作。为了加快处理速度,我正在考虑在我的邮件集合上使用 Parallel.ForEach。该循环创建了我的邮件项目处理 (clsMailItemProcess) 类的一个实例,并将邮件项目传递给它并对其进行处理。

处理每个邮件项目的规则都包含在数据库模式中,这样可以更轻松地配置规则。有许多规则可以识别电子邮件中的参考号,每个规则都有许多可能的方法来识别该号码。任务循环遍历规则,然后根据首先匹配的规则处理电子邮件。

我正在寻求有关使用 DbContext 的最佳方式的帮助。

  • 我是否应该在 Parallel.ForEach 之外创建它,然后传递一个 对 clsMailItemProcess 类的引用?根据我正在阅读的内容 可能会导致问题,因为 DbContext 不是线程安全的,这可能 解释我在极少数情况下看到的错误,尽管它有效 95% 的时间没有问题。我假设(也许错误地,我是 EF 的新手)这会减少数据库调用)
  • 是否应该在我的 clsMailItemProcess 类中创建一个新的 DbContext 并在其中使用它?这会增加对数据库的调用
  • 我是否应该创建 DbContext 并将其规则转换为我想要的对象? 然后可以根据需要传递我的应用程序

我应该指出我的 DbContext 没有更改,并且没有将更改写回数据库。

【问题讨论】:

  • 如果你将上下文传递给并行的ForEach,你会遇到问题——DbContext 不是线程安全的并且会爆炸。
  • 那么创建/阅读这些规则相对于每项任务的成本是多少?您的目标是多少?如,现在需要多少时间,您需要什么时间才能满足您的要求?
  • 我还没有为线程的创建/读取计时;将是我明天的任务。我的主要目标是将数据库调用次数减少到最低限度,以将流量保持在最低限度

标签: c# entity-framework parallel-processing dbcontext


【解决方案1】:

给定:

我应该指出我的 DbContext 没有更改,并且没有将更改写回数据库。

然后:

我是否应该创建 DbContext 并将其规则转换为对象,然后我可以根据需要在我的应用程序中传递这些对象

是的。这样做。

【讨论】:

  • 谢谢。我有点假设我应该这样做,但想要对我的想法进行一些确认。事实证明,这并没有像我想象的那样发生大的代码更改。
【解决方案2】:

我会在我的 Parallel.ForEach 调用中获得一个新的 DbContext。将上下文传递给多个线程可能会出现问题,尤其是如果您的规则在污染上下文方面具有某种类型的副作用。

您确定这需要并行完成吗?在我的一些宠物项目中,我需要解决类似的工人问题。我会有一个可以轮询集合以进行更改的类。当该类看到它有工作要做时,它会使用它的新工作负载启动 clsMailItemProcess。

这将有助于降低复杂性(嗯,它应该如此)以及让我隔离我的 clsMailItemProcess 代码。

【讨论】:

  • 没有副作用。处理每个邮件项目最多可能需要 4 或 5 秒,具体取决于邮件项目是什么以及它具有哪些附件。鉴于每小时将有数百封邮件,我想确保尽快处理它们,尽管还没有人定义他们希望多久处理一次邮箱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2011-09-27
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多