ASP.NET中的异步任务

我正在尝试强制ASP.NET站点在启动时将大量对象预加载到缓存中。 每个对象生成需要2-10秒,这意味着顺序加载1200多个对象需要40分钟才能完成。

我显然不希望该网站需要40分钟才能启动,因此只需在Application_Start中坚持预加载程序就不是一个选择。 我无法将其移到Web应用程序(即Windows服务或外部进程)的上下文之外,因为我需要访问缓存。 理想情况下,此任务将异步执行,同时让网站继续开展业务。 一位同事建议使用BackgroundWorker类来分拆新线程,这听起来是一个非常好的解决方案。 但是,据我所知,该特定类实际上并不适用于ASP.NET,而是适用于WinForms。 我担心线程可能会在它完成之前被杀掉。

  • BackgroundWorker类是否可以安全地在ASP.NET应用程序中使用?
  • 还有什么其他方法可以解决这个问题?

更新:

我将研究Windows AppFabric以获得更好的缓存,我可以从Web应用程序外部加载。 但是,在那之前我必须继续使用ASP.NET Cache和BackgroundWorker类。 它没有用,我问了一个新问题, 从新线程将对象加载到缓存中 。

另一种方法是使用数据库支持的缓存。 这样,您的Windows服务(例如)可以写入数据库,但仍可以从ASP.NET应用程序访问它。

例如,请参阅Microsoftfunction强大的企业库缓存应用程序块 (尽管还有很多其他的)。 我们使用它来共享50个网站之间的缓存,并在一夜之间从控制台应用程序填充缓存。

无论您如何生成缓存(进程内或进程外),使用数据库备份它都是明智的,否则如果重新启动应用程序,大多数映像将无法使用40分钟或更长时间。

你需要一个持久的视图模型商店!

例如,执行这些搜索并将结果存储在文档数据库中。 看看RavenDb 。 有了它,您可以将任何对象序列化到数据库中,并在查询数据时获得次秒响应时间。

然后,您可以使用任何内容来执行工作,并使用ASP.NET Web应用程序进行演示。

使用任务并行库 (如果您使用.Net 4.0)。 TPL的每个实现都是针对特定主机设计的,并且有一个用于ASP.NET,这意味着您拥有自己的TaskScheduler和SynchronizationContext,它们符合IIS在线程和线程上下文时所遵循的规则。

有一篇非常好的MSDN文章解释了不同的TPL行为。

如果您熟悉Lambda表达式,则使用TPL非常简单,并为您节省大量管理线程和线程池的地下代码。

是 – 您可以启动不同的工作线程(或后台工作者类)来加载缓存。 但是,您无论如何都必须支持缓存元素的按需(转弯)加载,因为在您的缓存完全准备之前可能需要它。

此外,根据您的应用程序负载/规模,您需要考虑由某些持久性存储支持的进程外缓存服务器或缓存(出于性能原因,您仍然需要进程内缓存,例如ASP.NET缓存)。 这种方案的优点是缓存在应用程序重启时的有效性,相同的缓存可以支持集群中的多个Web服务器,缓存失效/更新可以通过集中控制器等来处理。当然,如上所述,我会在这里查看需要它。