我正在开发一项 Web 服务,以从第 3 方提要中读取数据,对其进行一些修改并存储,然后将其返回给我的客户。它只需要定期从第 3 方站点更新。它将在 Azure 中作为 Web 角色的 WCF 服务运行。
起初我以为我会一直调用我的 parsefeed 方法,但如果上次更新太早,则让该调用返回...
public void ParseFeed()
{
if (DateTime.Now > lastrun.AddMinutes(1))
{
//Fetch updated data into something shared here.
//thedata is a public static in Global class
thedata = fetchdata();
lastrun=DateTime.Now;
}
}
但我猜,由于提取可能需要 1-2 秒(它是一种 Web 服务),因此多个用户将同时点击该代码。
from http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607 Because static members of any class, including an application class, are not thread-safe, the user code must provide appropriate locking for access to static members. This applies to any static member that you add to the application class.
我可以使用锁定(不确定如何使用)编辑:大量信息 here
我可以避免使用静态变量并使用缓存,并将我的数据放入其中(但这会在过期时被删除,并且多个用户会尝试获取数据)
我可以使用其中包含虚假数据项的缓存(基本上用作计时器)并在其过期时刷新 - 但即使没有人访问该站点,它也会刷新。 (也可能不是线程安全的)
我不能真正使用输出缓存,因为客户端查询我返回的数据的方式可能使每个请求都是唯一的:我的服务根据请求进行排序和过滤
顺便说一句,我不担心 Azure 上多个实例的结果一致性。每个都可以获取自己的状态,因此我不需要在多个服务器上共享状态。
我觉得有一个简单的解决方案,我完全错过了。想法?
最佳答案
从你的问题来看,它看起来像:
- 提供超过一分钟的数据是 Not Acceptable
- 如果两个服务实例由于刷新时间不同步而返回不同的数据是可以接受的
- 在刷新数据时调用方阻塞 1-2 秒是可以接受的
假设这些都是真的,那么最简单的解决方案就是使用静态变量来存储数据,并在整个检查/刷新 block 周围使用 lock
结构。我什至懒得尝试做任何像双重检查锁定模式这样聪明的事情;锁争用根本不会成为问题,因为与操作 Web 服务的开销相比,在临界区花费的时间将变得微不足道,除非它正在阻塞并且无论如何每个人都必须阻塞。
关于c# - 如何在 C# 中构建 Web 服务缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4283889/