【问题标题】:MVC3 - using AsyncController to prepopulate ObjectCache from databaseMVC3 - 使用 AsyncController 从数据库预填充 ObjectCache
【发布时间】:2011-09-15 18:54:11
【问题描述】:

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

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

我应该查看AsyncController 来执行此操作吗?有什么建议吗?

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

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

【问题讨论】:

  • #4 是我特别关心的。 1-3 我可以做,但是如何让其他请求等待是我要确保我做的正确。

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


【解决方案1】:

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

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

  1. 如果在缓存中找到数据,则立即返回结果。
  2. 如果在缓存中未找到数据,则启动 2 个并行异步任务来执行搜索。
  3. 同步这些任务,以便在它们都完成后填充缓存并返回最终结果。

此外,如果您要使用 AsyncController 路线,请确保使用异步 ADO.NET API 来查询您的数据库 (command.BeginExecuteResult/command.EndExecuteResult),以便您可以充分利用 I/O 完成端口并且不会阻塞执行昂贵的搜索操作期间的工作线程。

【讨论】:

  • 我相信我可能错误地陈述了我想要的行为并更新了问题。
【解决方案2】:

我最终不必使用 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;
  }
}

【讨论】:

    猜你喜欢
    • 2017-10-18
    • 1970-01-01
    • 2014-12-02
    • 2012-10-07
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多