我们正尝试在具有WCF服务的IIS环境中使用Singleton。
我们在此链接http://csharpindepth.com/articles/general/singleton.aspx
中遵循第六版中的建议 private static readonly Lazy<VedtaksbehandlingRuleService> lazy = new Lazy<VedtaksbehandlingRuleService>(() => new VedtaksbehandlingRuleService());
public static VedtaksbehandlingRuleService Instance { get { return lazy.Value; } }
private VedtaksbehandlingRuleService()
{
m_Container = StaticServiceContainer.Instance;
logger = m_Container.Resolve<ILoggerUtility>();
InitRuleService();
}
使用:
调用VedtaksbehandlingBusObjResponse resp = VedtaksbehandlingRuleService.Instance.BehandleVedtak(req);
当我们在单元测试中尝试此代码时,它可以正常工作。
当我们将它部署到IIS时,它适用于第一个调用者,它可以多次调用WCF服务而不会出错。
但是如果另一个客户端调用该服务,则会使用以下文本获得异常:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Receiver</s:Value>
<s:Subcode>
<s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="nb-NO">Tjenestekallet vedtaRefusjonskravOgBeregnPensjon feilet</s:Text>
</s:Reason>
<s:Detail>
<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true" />
<InnerException>
<HelpLink i:nil="true" />
<InnerException i:nil="true" />
<Message>Failure to create a Deployment Manager Server Manager for 'VedtaksbehandlingRuleServiceDManager'</Message>
<StackTrace>
Server stack trace: at com.blazesoft.server.deploy.manager.NdDeploymentManager.createDeploymentManagerServerManagers(NdDeploymentManagerConfig config) at
com.blazesoft.server.deploy.manager.NdDeploymentManager.configure() at
com.blazesoft.server.deploy.manager.NdDeploymentManager.createDeploymentManager (NdDeploymentManagerConfig deploymentManagerConfig) at
XXX.Liv.Pensjon.Forretningstjenester.Regelserver.DManager..ctor(String dManagerConfig) at
XXX.Liv.Pensjon.Forretningstjenester.Regelserver.RuleServerFactory.CreateRulesServer[T](String serverConfig, String dmanagerConfig, ILoggerUtility logger) at
XXX.Liv.Pensjon.Forretningstjenester.Vedtaksbehandlingstjeneste.VedtaksbehandlingRuleService.CreateRuleServer() at
XXX.Liv.Pensjon.Forretningstjenester.Vedtaksbehandlingstjeneste.VedtaksbehandlingRuleService.<.cctor>b__0() at
System.Lazy`1.CreateValue()
Exception rethrown at [0]: at
com.blazesoft.server.deploy.manager.NdDeploymentManager.createDeploymentManagerServerManagers(NdDeploymentManagerConfig config) at
com.blazesoft.server.deploy.manager.NdDeploymentManager.configure() at
com.blazesoft.server.deploy.manager.NdDeploymentManager.createDeploymentManager(NdDeploymentManagerConfig deploymentManagerConfig) at
XXX.Liv.Pensjon.Forretningstjenester.Regelserver.DManager..ctor(String dManagerConfig) at
XXX.Liv.Pensjon.Forretningstjenester.Regelserver.RuleServerFactory.CreateRulesServer[T](String serverConfig, String dmanagerConfig, ILoggerUtility logger) at
XXX.Liv.Pensjon.Forretningstjenester.Vedtaksbehandlingstjeneste.VedtaksbehandlingRuleService.CreateRuleServer() at
XXX.Liv.Pensjon.Forretningstjenester.Vedtaksbehandlingstjeneste.VedtaksbehandlingRuleService.<.cctor>b__0() at
System.Lazy`1.CreateValue() at
System.Lazy`1.LazyInitValue() at
XXX.Liv.Pensjon.Forretningstjenester.Vedtaksbehandlingstjeneste.Vedtaksbehandlingstjeneste.vedtaRefusjonskravOgBeregnPensjon(vedtaRefusjonskravOgBeregnPensjonRequest1 request)
</StackTrace>
<Type>com.blazesoft.server.deploy.manager.NdDeploymentManagerException</Type>
</InnerException>
<Message>Tjenestekallet vedtaRefusjonskravOgBeregnPensjon feilet</Message>
<StackTrace>
at
XXX.Liv.Pensjon.Forretningstjenester.Vedtaksbehandlingstjeneste.Vedtaksbehandlingstjeneste.vedtaRefusjonskravOgBeregnPensjon(vedtaRefusjonskravOgBeregnPensjonRequest1 request) at
SyncInvokevedtaRefusjonskravOgBeregnPensjon(Object , Object[] , Object[] ) at
System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
</StackTrace>
<Type>System.Exception</Type>
</ExceptionDetail>
</s:Detail>
</s:Fault>
</s:Body>
</s:Envelope>
我们没有设置实例化模式,所以应该是每次调用。该服务是每次调用,但在堆栈中我们有一个用于访问规则引擎的类,它必须是一个单例
任何人都知道是什么导致了这个问题,或者有更好的解决方案?
答案 0 :(得分:1)
我认为Lazy<T>
没有错 - 它会按预期为AppDomain
创建一个单例实例。
也许您的问题是IIS托管:
因此,重要的是您可能需要验证是否创建了多个应用程序域。您可以使用Process Explorer
检查w3wp.exe。转到属性&gt; .NET程序集 - 您将看到在工作进程中创建的所有appdomains。
如果你真的想要单身行为,你可能想重新考虑你的WCF托管机制。
PS:默认实例化模式是每个会话 - 不是每次通话。
答案 1 :(得分:0)
你的方法有很多问题,但只是为了解决你的问题 - 如果你需要的是一个每个调用对象(静态是为整个AppDomain共享)然后使它成为ThreadStatic,提供一个Clear()方法它并在EndRequest事件上调用它。这样,没有2个单独的调用将共享该对象,并且您将获得“懒惰”行为。