MVC3 - 使用AsyncController从数据库预填充ObjectCache

时间:2011-09-15 18:54:11

标签: asp.net-mvc-3 asynchronous asynccontroller

我有一个表单,可以通过AJAX搜索两个不同的数据源。数据相对较小,但返回的速度很慢。

我构建了一个缓存层来存储第一个查询后的完整结果...但是,我想在用户执行搜索之前使用数据填充缓存。

我应该看AsyncController这样做吗?有什么建议吗?

我想要的行为是(更新):

  1. 用户请求某个控制器的任何ActionABC(不一定是搜索操作)
  2. 服务器端,该操作检查缓存并异步请求数据(如果为空)
  3. 当缓存继续填充服务器
  4. 时,ActionABC返回请求的视图
  5. 如果用户随后在填充缓存时执行搜索,则他们的请求会一直等到缓存填充完成,否则缓存数据立即可用

2 个答案:

答案 0 :(得分:0)

只有当您可以并行执行2次搜索时,您才能从异步控制器中获益。

在这种情况下,你的逻辑可能是:

  1. 如果在缓存中找到数据,则立即返回结果。
  2. 如果在缓存中找不到数据,则执行2个并行异步任务来执行搜索。
  3. 同步这些任务,以便一旦完成,就会填充缓存并返回最终结果。
  4. 此外,如果您要使用AsyncController路由,请确保使用异步ADO.NET API查询数据库(command.BeginExecuteResult / command.EndExecuteResult),以便充分利用I / O完成端口并且在执行昂贵的搜索操作期间不要阻止工作线程。

答案 1 :(得分:0)

我最终不必使用AsyncControllers。

我使用任务工厂“激活并忘记”在调用控制器时最初加载数据的调用。

Task.Factory.StartNew(() => { var x = GetData(); });

在“GetData”调用内部,我使用LOCK强制后续调用等待缓存填充(地址#4)

private static object ThisLock = new object();

protected MyData GetData()
{
  if(<MyData in cache>)
    return MyData from cache;

  lock(ThisLock)
  {
    // just entered lock, see if cache was set by previous blocking thread
    if(MyData in cache>)
      return data from cache;

    ... load MyData from database ... 

    ... save MyData  to cache ... 

    return MyData from cache;
  }
}