4

我正在开发一项网络服务,以从 3rd 方提要中读取数据,对其进行一些修改并存储它,然后将其返回给我的客户。它只需要定期从第 3 方站点更新。它将作为 WCF 服务在 Azure 中的 Web 角色中运行。

起初我以为我总是会调用我的 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 服务),因此多个用户会同时访问该代码。

来自http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607 因为任何类(包括应用程序类)的静态成员都不是线程安全的,所以用户代码必须为访问静态成员。这适用于您添加到应用程序类的任何静态成员。

  • 我可以使用锁定(不确定如何) 编辑:这里有很多信息

  • 我可以避免使用静态变量并使用缓存,并将我的数据放入其中(但在到期时会被删除,并且多个用户会尝试获取数据)

  • 我可以使用带有假数据的缓存(基本上作为计时器)并在过期时刷新 - 但即使没有人访问该站点也会刷新。(也可能不是线程安全的)

  • 我不能真正使用输出缓存,因为客户端以一种可能使每个请求唯一的方式查询我返回的数据:我的服务根据请求进行排序和过滤

顺便说一句,我不担心 Azure 上多个实例的结果一致性。每个人都可以自己获取,所以我不需要在多个服务器上共享状态。

我觉得有一个简单的解决方案,我完全错过了。想法?

4

2 回答 2

1

由于您可能从缓存中读取的次数多于写入的次数,因此我将使用ReaderWriterLockSlim来确保多个线程可以同时读取数据但不会写入数据。我还将确保缓存的数据是不可变的,以确保它不会被消费者更改。

于 2010-11-26T11:23:56.363 回答
1

从你的问题来看,它看起来像:

  • 提供超过一分钟的数据是不可接受的
  • 如果两个服务实例由于刷新时间不同步而返回不同的数据是可以接受的
  • 数据刷新时调用者阻塞 1-2 秒是可以接受的

假设这些都是真的,那么最简单的解决方案就是使用静态变量来存储数据,并lock在整个检查/刷新块周围构造一个结构。我什至不会费心尝试做任何聪明的事情,比如双重检查锁定模式。锁争用根本不会成为问题,因为与操作 Web 服务的开销相比,在关键区域花费的时间将变得微不足道,除非它被阻塞并且每个人都必须阻塞。

于 2010-11-26T11:46:20.783 回答