让多个请求等待第一个请求完成(缓存)

Lau*_*nSt 4 c# asp.net caching

我有一个web api,它有一些get方法,可以将一些分布式查询引发到运行时间很长且cpu昂贵的多个系统.所以我们添加了一个输出缓存.像魅力一样工作,在第一个查询处理后,它非常快.

所以现在我发布了一个(可能是常见的?)问题.想象一下,缓存失效或过期的情况(出于某些原因),而不是一次一个客户端调用web api而是100个客户端.目前发生的是100个客户端开始运行长时间运行的查询,并且cpu爆炸到100%,服务器实例崩溃并且不再响应.我基本上想要的是,只有第一个请求执行处理并让所有其他请求等到他完成查询并将结果添加到缓存.然后所有其他人都可以从缓存中获得响应.

我知道有大约1000种方法可以实现它,但我想知道是否有一般模式或最佳实践?或者我必须实施锁?或者使用TPL或者什么?坦率地说,我不知道从哪里开始?

非常感谢你提前.

编辑除了下面非常好的答案,我还发现了这篇文章:http: //www.asp.net/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows -azure /队列为中心的工作模式

Mat*_*zer 6

期望的方式是使用消息队列或服务总线.将您的任务排入队列并在构建缓存时停止将它们出列.

这更容易处理,因为它只是暂停后台服务(例如,您可以从Windows服务实现消息队列/服务总线处理 - 您可能需要查看Topshelf -)并恢复它.

您的API应该排队任务而不是直接处理它们.

可能的消息队列:

在你的情况下,我会采用MSMQ方式,因为这是一个简单的场景,你只想将消息入队/出列...

如果我在与Web API相同的过程中需要它,该怎么办...

马蒂亚斯非常感谢你的回答和好的建议.如果我被迫采用进程方式,你会采用什么方式,所以在与web api托管相同的过程中这样做?

一个简单的解决方案可能是模拟不可靠的排队系统使用ConcurrentQueue<T>和创建任务处理器线程,该线程在重建缓存时可能会暂停或恢复.

如果您在IIS上托管WebAPI,我会切换到在一个进程中托管它,也称为自托管.了解此阅读此WebAPI OWIN/Katana自托管教程.