IIS7中的WCF应用程序:丢失单例实例
我有一个WCF应用程序,具有多个WSDL Web服务,托管在Windows Server 2008 64位上的IIS7中 当调用第一个webservice方法时(无论首先调用什么),应用程序要求一个单例被分配一些配置值一次 编辑:系统后端需要使用这种单例方法 我只分配了一次配置,但值再次变为空 以下是代码(简化):IIS7中的WCF应用程序:丢失单例实例,wcf,iis-7,singleton,Wcf,Iis 7,Singleton,我有一个WCF应用程序,具有多个WSDL Web服务,托管在Windows Server 2008 64位上的IIS7中 当调用第一个webservice方法时(无论首先调用什么),应用程序要求一个单例被分配一些配置值一次 编辑:系统后端需要使用这种单例方法 我只分配了一次配置,但值再次变为空 以下是代码(简化): WebserviceGlobalInitializer.InitStuff()仅被调用一次。仍然SingletonSettings.SomeValue变为null 这个问题是随机发生
WebserviceGlobalInitializer.InitStuff()
仅被调用一次。仍然SingletonSettings.SomeValue
变为null
这个问题是随机发生的
我试过了
1) 从基类中的普通构造函数调用WebserviceGlobalInitializer.Initialize()
2) 注释掉:Initialized=true
希望每次都能初始化设置(造成巨大的开销,所以这不是一个长期的解决方案)
值仍然变为空
有什么想法吗?您可以使用WCF运行时基础设施为您解决这个问题。尝试将以下属性添加到WebService类:
[ServiceBehavior(
ConcurrencyMode=ConcurrencyMode.Multiple,
InstanceContextMode=InstanceContextMode.Single)]
通过进程回收,所有不处于会话状态或应用程序状态的状态都将消失在黑洞中。这让人大开眼界,包括静态变量,其中一个是singleton实例
我的直觉是,singleton的InstanceContextMode已作为ASP.NET应用程序状态中的变量实现。为了验证这一点,我今天将做一些反射,并更新我的答案
更新
不,不是这样的使用process recycling,即使您将WCF实例模式设置为Single,也会丢失使用process recycling时singleton实例的所有状态(例如计数器等)。经过几天的搜索,我找到了问题的根源。阿利奥斯塔德的回答给了我一个暗示 我的Web服务使用行为配置。一个有身份验证,一个没有身份验证。 身份验证/会话处理在加载Web服务之前调用的
IDispatchMessageInspector
中实现
当回收应用程序池时,使用my webservice的应用程序处于联机状态时出现问题。然后应用程序将使用经过身份验证的行为向Web服务发出请求。
然后,IDispatchMessageInspector
实现将尝试加载设置,但它们尚未从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";
}
}