WCF: пользовательские ошибки ServiceHostFactory после приостановки пула приложений для NetMsmq, но не Http

Я создал собственную фабрику хостов для поддержки обслуживания на основе контейнеров и несовершенного асинхронного отмены. Служба создается на основе каждого вызова:

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 просто хранит данные до тех пор, пока я не обращаюсь к сервису через 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, возможно, есть ли лучшее место для его вызова?

1 ответ

Решение

Нашел это: http://blogs.msdn.com/b/wenlong/archive/2006/01/11/511514.aspx

Объясняет несколько вариантов работы с инициализацией активации не-http.

Другие вопросы по тегам