WCF:NetMsmq的应用程序池挂起后出现自定义ServiceHostFactory错误,但不是Http
本文关键字:错误 ServiceHostFactory 自定义 Http NetMsmq 应用 应用程序 挂起 程序池 WCF | 更新日期: 2023-09-27 18:27:07
我创建了一个自定义主机工厂来支持基于容器的服务实例化和不完美的异步取消。服务是在每次调用的基础上实例化的:
public class DIServiceHostFactory : ServiceHostFactory
{
protected IContainer Container { get; private set; }
public DIServiceHostFactory()
: this(ContainerFactory.GetContainerForMap<DIServiceHostFactory>())
{
}
public DIServiceHostFactory(IContainer container)
{
this.Container = container;
}
protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new DIServiceHost(this.Container, serviceType, baseAddresses);
}
}
public class DIServiceHost : ServiceHost
{
protected IContainer Container { get; private set; }
public DIServiceHost() : this(ContainerFactory.GetContainerForMap<DIServiceHost>()) { }
public DIServiceHost(IContainer container)
{
this.Container = container;
}
public DIServiceHost(IContainer container, Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses)
{
this.Container = container;
}
protected override void OnOpening()
{
Description.Behaviors.Add(CreateBehavior());
base.OnOpening();
}
protected virtual DIServiceBehavior CreateBehavior()
{
return new DIServiceBehavior(this.Container);
}
}
public class DIServiceBehavior : IServiceBehavior
{
protected IContainer Container { get; private set; }
public DIServiceBehavior(IContainer container)
{
this.Container = container;
}
public virtual void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
protected virtual DIInstanceProvider ConstructProvider(ServiceDescription description)
{
return new DIInstanceProvider(description.ServiceType, Container);
}
public virtual void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>())
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider = ConstructProvider(serviceDescription);
}
}
}
public virtual void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
public class DIInstanceProvider : IInstanceProvider
{
protected Type ServiceType { get; private set; }
protected IContainer Container { get; private set; }
protected ILogger Logger { get; private set; }
public DIInstanceProvider(Type serviceType, IContainer container)
{
this.ServiceType = serviceType;
this.Container = container;
ILogger logger;
container.TryResolve<ILogger>(out logger);
this.Logger = logger;
}
public virtual object GetInstance(InstanceContext instanceContext, Message message)
{
if (this.Logger != null)
this.Logger.Info(message.ToString());
CancellationTokenSource cancellationToken = new CancellationTokenSource();
var s = this.Container.Resolve(this.ServiceType);
var service = s as ICancellableService;
if (service != null)
{
service.CancellationToken = cancellationToken.Token;
instanceContext.Faulted += (sender, e) => cancellationToken.Cancel();
instanceContext.Closing += (sender, e) => cancellationToken.Cancel();
}
return s;
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public virtual void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}
主要用途是通过netmsmq绑定,我注意到当我第一次启动应用程序时,客户端没有收到任何错误,MSMQ只保存数据,直到我通过web浏览器通过HTTP访问服务,我不确定此时是否会生成此错误。之后,它将处理整个队列,直到应用程序池因不活动而暂停(当前设置为20分钟)。然后我经常收到以下错误(但不是每个客户端请求,今天早上我的事件日志中有大约250个错误,队列中有1500多条消息等待):
WebHost failed to process a request.
Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/17653682
Exception: System.ServiceModel.ServiceActivationException: The service '/MerchReport/reportconsumer.svc' cannot be activated due to an exception during compilation. The exception message is: Object reference not set to an instance of an object.. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at United.UEL.WCF.DIInstanceProvider..ctor(Type serviceType, IContainer container)
at United.UEL.WCF.DIServiceBehavior.ConstructProvider(ServiceDescription description)
at United.UEL.WCF.DIServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
at System.ServiceModel.ServiceHostBase.InitializeRuntime()
at System.ServiceModel.ServiceHostBase.OnBeginOpen()
at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open()
at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity)
at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity)
--- End of inner exception stack trace ---
at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity)
at System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath, EventTraceActivity eventTraceActivity)
Process Name: w3wp
Process ID: 13740
MSMQ命中时,似乎没有配置我的容器。目前我在Global.asax.Application_Start事件中调用我的引导程序,有更好的地方可以调用它吗?
发现:http://blogs.msdn.com/b/wenlong/archive/2006/01/11/511514.aspx
解释用于处理非http激活初始化的几个选项。