3

我们正在开发一个基于 WCF 的系统。在这个过程中,我们试图锁定一些数据不被多个用户修改。所以我们决定有一个数据结构,它将包含执行锁定逻辑所需的信息(例如通过存储锁定对象的 ID)

我们遇到的问题是在会话之间保留该数据。无论如何我们可以避免执行昂贵的数据库调用吗?我不确定我们如何在 WCF 中做到这一点,因为它只能在打开的会话期间保存数据(在内存中)。

4

4 回答 4

4

服务实现类的静态成员在会话和调用之间共享。

于 2009-01-09T23:21:22.897 回答
3

正如 Jimmy McNulty 所说,一种选择是使用静态成员。我有一个 WCF 服务,它根据用户指定的 IP 地址打开网络连接。我的服务配置为 PerCall 服务实例模式。在每个会话中,我都会检查一个静态数据结构,以查看是否已经为指定的 IP 地址打开了网络连接。这是一个例子。

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    void Start(IPAddress address);
}

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class MyService : IMyService
{
    private static readonly List<IPAddress> _addresses = new List<IPAddress>();
    public void Start(IPAddress address)
    {
        lock(((ICollection)_addresses).SyncRoot)
        {
            if (!_addresses.Contains(address)
            {
                // Open the connection here and then store the address.
                _addresses.Add(address);
            }
        }
    }
}

按照配置,对 Start() 的每次调用都发生在其自己的服务实例中,并且每个实例都可以访问静态集合。由于每个服务实例都在单独的线程中运行,因此必须同步对集合的访问。

与在多线程编程中完成的所有同步一样,一定要尽量减少花在锁上的时间。在所示示例中,一旦第一个调用者获取锁,所有其他调用者必须等待直到锁被释放。这适用于我的情况,但可能不适用于您的情况。

另一种选择是使用单一服务实例模式,而不是 PerCall 服务实例模式。

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class MyService : IMyService
{ ... }

不过,从我读过的所有内容来看,PerCall 似乎更灵活。

您可以点击此链接了解两者之间的差异。

并且不要忘记实现您的服务的类就是这样 - 一个类。它像所有 C# 类一样工作。您可以添加静态构造函数、属性、事件处理程序、实现其他接口等。

于 2009-01-10T04:48:49.037 回答
0

也许像速度这样的缓存框架可以帮助你。

于 2008-11-09T14:10:56.837 回答
0

创建第二个类并将其 InstanceContextMode 设置为 single 并将所有昂贵的方法移到那里,然后在您的原始类中使用这些方法。

于 2008-11-09T15:26:26.453 回答