WCF PerCall共享资源锁定问题

时间:2014-05-01 02:58:59

标签: c# multithreading wcf synchronization locking

我正在编写一个不断来自不同来源的服务。服务需要在对单个共享资源的某些调用期间保留数据。在这种情况下,一个XML文件(我知道这是存储数据的愚蠢选择,但我无法控制该决定)。

所以我希望服务能够在

中运行
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

因为除了这种情况,我不需要会话,并且我的对象构造函数中的设置代码非常少。但是,静态变量不会在每次调用服务之间共享(它们会快速而激烈地进行)。因此,文件上的静态锁定不起作用。我很难学到这一点:

private string _dataFile;

private static object _lock = new object();

private MusicData Get(string fileName)
{
    lock (_lock)
    {
        using (var stream = File.OpenRead(fileName))
        {
            var serializer = new XmlSerializer(typeof(MusicData));
            return serializer.Deserialize(stream) as MusicData;
        }
    }
}

private void Put(string fileName, MusicData data)
{
    lock (_lock)
    {
        XmlSerializer x = new XmlSerializer(typeof(MusicData));
        using (TextWriter writer = new StreamWriter(fileName))
        {
            x.Serialize(writer, data);
        }
    }
}

这个地方最好的策略是什么?我不想仅仅因此而将InstanceContextMode更改为PerSession,并且任何类型的数据库解决方案都是不可能的。上面的代码导致了可怕的错误:

  

该进程无法访问该文件,因为该文件正由另一个进程

使用

1 个答案:

答案 0 :(得分:2)

在您描述的方案中,共享客户端对单个XML文件的访问权限,您可能需要考虑InstanceContextMode.SingleConcurrencyMode.Multiple一起使用,前提是您的服务是无状态的,线程安全的和可重入的。

使用InstanceContextMode.SingleConcurrencyMode.Multiple的WCF服务不应对您的方案中的任何性能问题负责。

单身人士服务是最终的可分享服务。当服务配置为单例时,无论连接到哪个服务端点,所有客户端都会彼此独立地连接到同一个众所周知的实例。单身人士服务永远存在,只有在主人关闭后才会被处理掉。单个主机在创建主机时只创建一次。

http://msdn.microsoft.com/en-us/magazine/cc163590.aspx