我有一个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;
希望每次都能初始化设置(导致大量开销,所以无论如何都不是长期解决方案)
该值仍然为空。
有什么想法吗?
答案 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)]