我们正在开发基于WCF的系统。在此过程中,我们试图锁定一些数据,使其不被多个用户修改。所以我们决定建立一个数据结构,包含执行锁定逻辑的必要信息(例如存储锁定对象的ID)
我们遇到的问题是在会话之间保留数据。反正我们可以避免执行昂贵的数据库调用吗? 我不知道我们怎么能在WCF中这样做,因为它只能在打开的会话期间保存数据(在内存中)。
答案 0 :(得分:4)
服务实现类的静态成员在会话之间共享&调用。
答案 1 :(得分: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似乎更灵活。
您可以按照此link来了解两者之间的差异。
不要忘记实现您的服务的类就是 - 一个类。它像所有C#类一样工作。您可以添加静态构造函数,属性,事件处理程序,实现其他接口等。
答案 2 :(得分:0)
也许像velocity这样的缓存框架会帮助你。
答案 3 :(得分:0)
创建第二个类并将其InstanceContextMode设置为single并在那里移动所有昂贵的方法,然后在原始类中使用该方法。