【问题标题】:Check to see if there are active WCF calls on the IIS Server检查 IIS 服务器上是否有活动的 WCF 调用
【发布时间】:2015-01-27 22:46:36
【问题描述】:

我在我的 WCF 服务中缓存了一堆数据。我有一个服务操作使缓存无效并重新获取它。

但是,如果我在服务调用过程中尝试重新获取,我很容易做出错误的计算。 (一半计算旧数据,一半计算新数据。)

所以,我计划在每次调用开始时检查一下我们当前是否正在尝试刷新数据。如果是,那我会等到我们完成刷新。

我遇到的问题是我需要一种方法来知道我所有的“进行中”呼叫都已结束。

WCF 服务有没有办法知道服务器上是否有其他调用正在进行?

(或者有没有更好的方法来刷新 WCF 服务的缓存数据?)

【问题讨论】:

    标签: .net multithreading wcf caching iis


    【解决方案1】:

    使用简单锁定(使用 lock 语句)或其他同步原语,例如ReaderWriterLockSlim,同步对共享资源的访问。

    在您的情况下,您的共享资源是缓存。您正在同时从多个线程访问缓存,读取或更新它。您真正想要实现的目标如下:

    1. 当您不更新缓存时,任何调用都可能同时从缓存中读取。
    2. 每当您需要更新缓存时,您的更新调用应等待所有读取操作完成。
    3. 在更新缓存时,其他调用(读取或更新)必须等到更新完成。

    ReaderWriterLockSlim 可以为您做到这一点。下面是一些基本的实现,展示了如何使用它:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    
    public class SynchronizedCache
    {
        private ReaderWriterLockSlim syncLock = new ReaderWriterLockSlim();
        private Dictionary<int, int> dictionary = new Dictionary<int, int>();
    
        public int Get(int key)
        {
            bool lockAcquired = false;
            try
            {
                syncLock.EnterReadLock();
                lockAcquired = true;
    
                // Get data from cache.
                var data = dictionary[key]; 
                return data;
            }
            finally
            {
                if (lockAcquired)
                    syncLock.ExitReadLock();
            }
        }
    
        public void Update()
        {
            bool lockAcquired = false;
            try
            {
                syncLock.EnterWriteLock();
                lockAcquired = true;
    
                // Do your update work here.
                var random = new Random();
                for (int i = 0; i < 100; i++)
                {
                    this.dictionary[i] = random.Next();
                }
            }
            finally
            {
                if (lockAcquired)
                    syncLock.ExitWriteLock();
            }
        }
    }
    

    现在,您只需要确保所有服务实例都使用相同的 SynchronizedCache 实例:要么将其设为单例,要么 - 甚至更好 - 使用依赖注入并将相同的缓存注入所有服务实例。或者使服务实例本身成为单例。您可能已经为此制定了解决方案。

    【讨论】:

    • 我需要第一个。但是 CQRS 是一个架构大修,我不知道如何使事务在数据库之外工作......有什么建议吗?我需要一个 WCF 解决方案。
    • 1.您从哪里获取缓存构成的数据? 2. 您的缓存是如何以及何时失效的?
    • 我从数据库中得到它(它是参考数据)。它因调用服务操作而无效,告诉我它需要刷新。 (所以,我的 SSIS 包运行(每隔一小时左右),然后我的“RefreshReferenceData”服务操作被调用。
    • 这就是你想要的吗? 1.) RefreshReferenceData 应该等到所有读取操作完成。 2.) 当RefreshReferenceData 正在运行时,其他调用可能不会从缓存中读取。 3.) RefreshReferenceData 一次只能运行一次。 4.) 当RefreshReferenceData 没有运行时,任何调用都可以同时从缓存中读取。
    • 是的。这是#1,我不知道该怎么做。这就是我发布这个问题的原因。我需要一种方法来知道对我的服务的所有调用都已退出。在更新参考数据之前,我可以阻止任何新调用,但我无法知道在进行更新之前我应该​​等待多长时间。 (我的调用长度可能会根据参数的复杂程度而有所不同。)
    【解决方案2】:

    使用 ConcurrencyMode = ConcurrencyMode.Single

    【讨论】:

      猜你喜欢
      • 2020-05-03
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多