IIS7中的WCF应用程序:丢失单例实例

时间:2010-10-13 07:49:09

标签: wcf iis-7 singleton

我有一个WCF应用程序,有多个WSDL Web服务,托管在Windows Server 2008 64Bit上的IIS7中。

当调用第一个webservice方法时(无论先调用什么方法),应用程序需要为一个单例分配一些配置值。

编辑:系统的后端需要使用此单例方法。

我获得了一次配置,但值再次变为空值....

这是代码(简化):

public class SingletonSettings 
{
    private static readonly SingletonSettings _s;

    public SingletonSettings Instance { get {return _s;} }

    public object SomeValue { get; set; }
}

public abstract class AbstractWebservice 
{
    static AbstractWebservice() 
    {
        WebserviceGlobalInitializer.Initialize();
    }

}
//Just a webservice
public class Webservice1 : AbstractWebservice, ISomeServiceConctract1 
{
    public void DoStuff1();
}

//Just a webservice
public class Webservice2 : AbstractWebservice, ISomeServiceConctract2
{
    public void DoStuff2();
}

internal class WebserviceGlobalInitializer
    {
        private static readonly object Lock = new object();
        private static bool Initialized = false;

        public static void Initialize()
        {
            lock (Lock)
            {
                if (!Initialized)
                {
                    InitStuff();

                    Initialized = true;
                }
            }
        }

        private static void InitStuff()
        {            
            string s = SingletonSettings.Instance.SomeValue = "just a ref";
        }
    }

WebserviceGlobalInitializer.InitStuff()仅被调用一次。仍然SingletonSettings.SomeValue变为空......

问题是随机发生的。

我试过了

1)从基类中的普通构造函数调用WebserviceGlobalInitializer.Initialize()

2)注释掉:Initialized = true;希望每次都能初始化设置(导致大量开销,所以无论如何都不是长期解决方案)

该值仍然为空。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

使用进程回收,所有未处于会话状态或应用程序状态的状态将消失在黑洞中。这令人大开眼界,包括静态变量,其中一个是单例实例。

我的直觉是单例的InstanceContextMode已在ASP.NET应用程序状态中实现为变量。为了检查这一点,我今天将做一些反思,并将更新我的答案。

<强>更新

没有它!!!! 通过进程回收,即使您将WCF Instancing模式设置为Single,也会丢失您对单例实例所具有的所有状态(例如计数器,无论如何)过程回收。

答案 1 :(得分:1)

经过几天的搜索,我找到了问题的根源。 Aliostad的回答给了我一个暗示。

我的网络服务使用行为配置。一个有身份验证,一个没有。 身份验证/会话处理在IDispatchMessageInspector中实现,该IDispatchMessageInspector在加载Web服务之前调用。

当应用程序池被回收时,使用我的Web服务的应用程序处于联机状态时发生问题。然后,应用程序将使用经过身份验证的行为向Web服务发出请求。 然后{{1}}实现将尝试加载设置,但它们尚未从webservice中的静态构造函数初始化....

感谢您的回答......

答案 2 :(得分:0)

您可以使用WCF运行时基础结构来为您处理此问题。尝试将以下属性添加到WebService类:

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