2013-11-22 41 views
1

我的MVC4应用程序使用代码优先的实体框架5.0。我想从计时器线程访问我的SQL Server数据。是否有任何理由不能实例化,使用和配置我在主ASP.NET工作线程上使用的相同派生DbContext类的实例? (是的,我使用相同的using()模式在主线程上实例化,使用和处理对象。)在后台线程上使用DbContext

一个小问题上下文:我的网站在数据库的表中有一个WebsiteEnabled字段。目前,我会为每个GET请求执行数据库提取以读取该值。我想更改代码以在后台线程上每15秒读取一次值,并将该值存储在GET请求可以读取的静态变量中。我知道如果你尝试在同一个线程上实例化同一个DbContext的多个实例,你会遇到问题;我不确定相同的限制是否适用于不同线程上相同DbContext的实例。

+1

我们还使用后台线程来检查电子邮件并每隔一段时间进行一次清理。只要你在后台线程上创建一个新的上下文(并将其处理掉),而不是尝试使用你的主应用程序线程中的那个上下文,那么你会没事的。 DbContext不是线程安全的,这意味着你不能在多个线程中共享它。这并不意味着你不能拥有多个线程,每个线程都有自己的数据库上下文副本。谨慎小心谨防并发问题(试图同时更新一行)。 – Tommy

+0

@Tommy:谢谢。请将此作为答案而不是评论,以便我可以接受为答案。 –

+0

没问题鲍勃,张贴为答案。就像我说的,只要你将DbContext本地化为一个线程,你就不会有任何问题。 – Tommy

回答

1

我们还使用后台线程来检查电子邮件,并在我们较大的MVC应用程序中经常进行清理。只要你在后台线程上创建一个新的上下文(并将其处理掉),而不是尝试使用你的主应用程序线程中的那个上下文,那么你会没事的。 DbContext不是线程安全的,这意味着您无法安全地跨多个线程共享它。这并不意味着你不能拥有多个线程,每个线程都有自己的数据库上下文副本。唯一的注意事项是注意并发问题(试图同时更新一行)。

1

静力和EF是混乱的食谱。在asp.net下,有1个应用程序池,有很多线程。存储静态如果你必须但不是上下文。所以一定要确保每个线程都有自己的上下文。

但是考虑到你的问题,有一个简单的开箱即用的解决方案我会用 在thr控制器中应该有缓存值。在GET方法 您可以缓存每个ID,在一段特定的时间... 值得检查。让IIS,ASP.NET为你工作。 :-)

[OutputCache(Duration = int.MaxValue, VaryByParam = "id", Location = OutputCacheLocation.ServerAndClient)] 
    public ActionResult Get(string id) { 
     // the value that can be cached is collected with a NEW CONTEXT ! 
+0

我不明白这个答案。我不想缓存页面输出;我想要缓存数据库读取操作。你可以请张贴更完整的例子吗? –

+0

dbcontext不是线程安全的。 App池使用多个线程。本示例使用IIS缓存ID xyz的get info结果。这会缓存您阅读的结果。缓存获取是一个非常普遍的要求。重用现有功能是我的建议。研究OutputCache属性。 –