检查 IIS 服务器上是否有活动的 WCF 调用
Check to see if there are active WCF calls on the IIS Server
我在我的 WCF 服务中缓存了一堆数据。我有一个使该缓存无效并重新获取它的服务操作。
但是,如果我在服务调用过程中尝试重新获取,我很容易做出错误的计算。 (旧数据计算一半,新数据计算一半。)
所以,我计划在每次调用开始时进行检查,看看我们当前是否正在尝试刷新数据。如果是,那么我会等到刷新完成。
我遇到的问题是我需要一种方法来知道我的所有 "In Progress" 呼叫都已完成。
WCF 服务有没有办法知道服务器上是否有其他正在进行的调用?
(或者是否有更好的方法来刷新 WCF 服务的缓存数据?)
使用简单锁定(使用锁定语句)或其他同步原语,例如ReaderWriterLockSlim,以同步对共享资源的访问。
在你的例子中,你的共享资源是一个缓存。您同时从多个线程访问缓存,读取或更新它。您实际想要实现的是以下内容:
- 当您不更新缓存时,任何调用都可以同时从缓存中读取。
- 每当您需要更新缓存时,您的更新调用应该等到所有读取操作完成。
- 当您更新缓存时,其他调用(读取或更新)必须等到更新完成。
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
实例:要么将其设为单例,要么 - 甚至更好 - 使用依赖注入并将相同的缓存注入所有服务实例。或者使服务实例本身成为单例。您可能已经有了解决方案。
使用并发模式 = ConcurrencyMode.Single
我在我的 WCF 服务中缓存了一堆数据。我有一个使该缓存无效并重新获取它的服务操作。
但是,如果我在服务调用过程中尝试重新获取,我很容易做出错误的计算。 (旧数据计算一半,新数据计算一半。)
所以,我计划在每次调用开始时进行检查,看看我们当前是否正在尝试刷新数据。如果是,那么我会等到刷新完成。
我遇到的问题是我需要一种方法来知道我的所有 "In Progress" 呼叫都已完成。
WCF 服务有没有办法知道服务器上是否有其他正在进行的调用?
(或者是否有更好的方法来刷新 WCF 服务的缓存数据?)
使用简单锁定(使用锁定语句)或其他同步原语,例如ReaderWriterLockSlim,以同步对共享资源的访问。
在你的例子中,你的共享资源是一个缓存。您同时从多个线程访问缓存,读取或更新它。您实际想要实现的是以下内容:
- 当您不更新缓存时,任何调用都可以同时从缓存中读取。
- 每当您需要更新缓存时,您的更新调用应该等到所有读取操作完成。
- 当您更新缓存时,其他调用(读取或更新)必须等到更新完成。
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
实例:要么将其设为单例,要么 - 甚至更好 - 使用依赖注入并将相同的缓存注入所有服务实例。或者使服务实例本身成为单例。您可能已经有了解决方案。
使用并发模式 = ConcurrencyMode.Single