【问题标题】:Multi-threading in ASP.net MVC3 with Code-First EF带有 Code-First EF 的 ASP.net MVC3 中的多线程
【发布时间】:2012-08-23 14:42:44
【问题描述】:

一直在为我的应用程序寻找多线程解决方案,但在尝试时不断收到随机的 NullReferenceException 错误,而不是在我连续运行每个错误并且一切顺利时。

我正在做的是计算从一个地方到另一个地方的旅程,然后计算回程。回程计算只是使用相同的过程,只是换了出发地和目的地。

在带有实体框架的 ASP.net MVC3 应用程序中使用多线程执行此操作听起来可行吗?我看过一些似乎 EF 存在问题的文章,但这些听起来只是当 DBContexts 在页面上共享时才会出现问题,而我在需要访问数据库的所有区域都使用了 Using 语句.有人在这里有经验吗?

我目前掌握的基本相关代码是这样的:

var outboundJourneyTask = Task.Factory.StartNew(() => BuildJourney(true));
var returnJourneyTask = Task.Factory.StartNew(() => BuildJourney(false));
Task.WaitAll(outboundJourneyTask, returnJourneyTask);

我希望每个任务都能重新开始,但由于空引用异常,我相信在第二个线程中,它正在尝试使用第一个内置的数组,而当它找不到某些元素,它会引发错误。

这听起来可能吗?有人知道这样做的更好方法吗?

编辑:我正在尝试一种不同的线程方法(见下文),但我的数组确实发生了一些奇怪的事情 - 以不同的方式循环它们并引发错误

Thread t1 = new Thread(ThreadMethod1);   
t1.Start();

Thread t2 = new Thread(ThreadMethod2);
t2.Start();

void ThreadMethod1(object state)
{
    BuildJourney(false);
    ManualResetEvent mre = (ManualResetEvent)state;
    mre.Set();
}
void ThreadMethod2(object state)
{
    BuildJourney(true);
    ManualResetEvent mre = (ManualResetEvent)state;
    mre.Set();
}

谢谢

【问题讨论】:

  • 您的BuildJourney 方法看起来如何?
  • 它太大了,因为它包含许多其他函数和计算,所以无法在此处发布!处理大约需要 7-10 秒,这就是我希望它们同时运行的原因。它包含几个数据库调用、几个计算并返回一个通用的视图模型列表。
  • 但在这种情况下,如果我们不知道您的通话可以共享哪些资源,我们将无法为您提供帮助。
  • 是的,我很感激。我将不得不将代码发布到外部某个地方 - 在这里的代码块中能够理解的内容太多了。现在,我承认我对线程的理解不是很好,但我认为你能够做到这一点,所以一个新线程是完全独立的,即它们不共享任何资源。你知道这是否可能吗?
  • 是的,有可能。 “不共享任何资源”是关键部分——它们可以以线程安全(只读、锁定、不依赖状态)的方式共享资源。

标签: c# asp.net multithreading asp.net-mvc-3 entity-framework


【解决方案1】:

“这听起来可行吗..?” 是的,当然。

易于实施.....也许不是。

Thread t1 = new Thread(ThreadMethod1)

是在 .net 4+ 框架中进行多线程处理的一种过时但不一定已弃用的方法。从您发布的内容来看,没有任何迹象表明您不能使用任务。任务工厂是在 TPL 中管理任务的更现代的方式,但我个人发现它有一些怪癖。如果我是你,我会尝试这样做:

   Task T = new Task(() =>
                {
                   BuildJourney(true);
                });
                Task T2 = T.ContinueWith((antecedent) =>
                {
                     BuildJourney(false);
                });

这将确保 T2 仅在 T1 回来时运行。不过,正如 Ladislav 所说,BuildJourney 方法可能不是线程安全的。这至少会让你更进一步确定你的线程故障在哪里。您可能想要调查正确的异步和多线程调试。它比简单的 F5 稍微复杂一些。像pluralsight 和代码项目这样的网站有很好的调试和编写.net 线程编程的教程。

你有一个很好的开始。祝你好运!

【讨论】:

  • 我越了解正在发生的事情,我就越认为您的 BuildJourney 类不能运行多线程。至少不是没有一些变化。如果您一次只希望一个 Buildjourney 实例在主线程之外运行,则上述代码将起作用。您可能必须重构 BuildJourney。此外,方法越复杂,线程安全的可能性就越小。
  • 确实 - 我认为您完全正确。从您发布的 MSDN 库链接来看,在我的所有进程中都有很多东西不是线程安全的,这将解释我在线程中运行它时遇到的奇怪错误。我想我需要重构,但我快要开始使用这个项目了——我只是想让它更快,所以我现在重构还是在我们上线之后我可能会做出选择而不是啤酒今晚!感谢您的回答肖恩,非常有帮助。
  • 只是庞大的数据量让事情变得停滞不前 - 我使用分析器将时间从最初的一分半钟缩短到大约 7-10 秒,所以我已经完成了行。我使用 ajax 和部分视图,因此在算法完成每个部分时会显示数据,但最好在 10 秒内完成这两个功能。不过,我可能会将其留给“第二阶段修正案”!
  • Definitley 是个好主意。有一些 nuget Lint 包可能会提供更多帮助。您的数据是否来自数据库?如果是什么种类?您是否有能力进行任何数据库改进?
  • 它是 sql server - db 调用很快,因为它在任何需要的地方都建立了索引,但所需的处理增加了时间。不过,我会检查一下 Lint 包——这可能会有所帮助。再次感谢
猜你喜欢
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 2013-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多