【问题标题】:How to share static object across processes in WCF?如何在 WCF 中跨进程共享静态对象?
【发布时间】:2012-02-27 16:25:32
【问题描述】:

背景:

我向this question 询问了有关为我的 WCF 服务创建缓存提供程序结构的问题。我现在已经实现了这个设计,但是我在测试中注意到的是,提供程序实际上并没有被缓存。我怎么知道这个?我在我的服务中添加了以下调试级日志记录:

private static readonly IDictionary<string, XmlLoaderProviderBase> _providerDictionary =
    new Dictionary<string, XmlLoaderProviderBase>();

public void Load(LoadRequest loadRequest)
{
    XmlLoaderProviderBase xmlLoader;
    if (_providerDictionary.ContainsKey(loadRequest.TransferTypeCode))
    {
        // Use cached provider...
        xmlLoader = _providerDictionary[loadRequest.TransferTypeCode];

        Logger.Log.DebugFormat("Found cached provider: {0} for transfer type: {1}",
            xmlLoader.GetType(), loadRequest.TransferTypeCode);
    }
    else
    {
        // Instantiate provider for the first time; add provider to cache...
        xmlLoader = XmlLoaderProviderFactory.CreateProvider(loadRequest.TransferTypeCode);
        _providerDictionary.Add(loadRequest.TransferTypeCode, xmlLoader);

        Logger.Log.DebugFormat("Instantiating provider: {0} for transfer type: {1}",
            xmlLoader.GetType(), loadRequest.TransferTypeCode);
    }
    xmlLoader.Load(loadRequest);
}

我注意到,无论我调用多少次服务,提供程序总是被实例化(它永远不会找到缓存的版本)。值得庆幸的是 log4net 非常有用,它表明对服务的每次调用都在它自己的唯一进程中运行(即它有一个唯一的进程 ID)。因此,提供者永远不会被缓存。我怎样才能让它真正缓存提供程序,并跨进程读取该字典?这甚至可能吗?

我也在 SO 上阅读了与此类似的问题,我注意到了 InstanceContextMode 设置。我不认为我想要这个,因为我认为这会损害性能(我错了吗?远吗?)简而言之,我希望在所有进程/服务实例之间共享 _providerDictionary ...请帮忙!

【问题讨论】:

  • WCF 服务调用在单独的进程中运行。
  • 没有静态对象这样的东西。你可以有静态类和静态成员
  • @JohnSaunders - 我会花一美元买它,但有几点:1)对服务的连续调用每次都显示不同的 PID,以及 2)检查是否提供者已经存在永远不会评估为真。愿意详细说明您的立场并在这里为我提供更多见解吗?
  • 如何托管您的 WCF 服务?在 IIS 或自托管中?我认为这主要取决于您的主机是否重新启动服务进程。我会使用 InstanceContextMode。除非你衡量它,否则永远不要担心性能。
  • 如果您每次都获得一个新进程,那么您最好找出导致原始进程崩溃的原因。

标签: c# .net wcf caching static


【解决方案1】:

我要偷@slfan 的评论:

使用

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode=InstanceContextMode.Single)]

默认 InstanceContextMode 是 PerSession。

【讨论】:

    【解决方案2】:

    我会考虑使用 System.Runtime.Caching.ObjectCache / MemoryCache 创建一个自定义缓存框架。据我所知,这应该可以跨进程访问。它也是线程安全的。

    查看以下链接:

    http://technovivek.blogspot.com/2013/08/c-in-memory-cache-using-net-40-object.html

    http://www.codeproject.com/Articles/290935/Using-MemoryCache-in-Net

    【讨论】:

      猜你喜欢
      • 2010-10-20
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 1970-01-01
      • 2011-07-22
      • 1970-01-01
      相关资源
      最近更新 更多