会话之间的WCF数据持久性

问题描述 投票:3回答:4

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

我们遇到的问题是在会话之间保持数据。 反正我们可以避免执行昂贵的数据库调用吗? 我不知道我们怎么能在WCF中这样做,因为它只能在打开的会话期间持久保存数据(在内存中)。

wcf persistence session
4个回答
4
投票

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


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#类一样工作。 您可以添加静态构造函数,属性,事件处理程序,实现其他接口等。


0
投票

也许像velocity这样的缓存框架会帮助你解决问题。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.