如何停止从另一个Windows应用程序在IIS上托管的WCF服务(使用net.MSMQ绑定)

时间:2012-06-21 07:21:10

标签: wcf

我有一个使用在IIS上托管的MSMQ的WCF服务。我想创建一个Windows应用程序,它可以阻止WCF服务选择MSMQ消息。一旦我在队列中看到MSMQ消息,我需要单击一个按钮并启动WCF服务以在MSMQ中选择消息。代码示例将被关闭。

3 个答案:

答案 0 :(得分:1)

IIS不是托管MSMQ客户端的合适容器。这是因为当流量较低时应用程序池卸载时,队列客户端也会卸载。此行为是自动的,您无法控制它。

在Windows服务中托管您的客户端要好得多。但是,您需要的“按需消费”功能并不容易实现,标准绑定当然不支持这种功能。

我能建议的最好的方法是在收到消息后立即使用该消息并将其保留在某处,直到用户单击该按钮为止,您可以随意执行任何操作,因为消息中的数据已经可用。

答案 1 :(得分:1)

我通过应用解决方法解决了这个问题。我在另一台机器上创建了另一个队列。在config中将WCF客户端端点地址的地址更改为此队列。我创建了另一个外部应用程序,它将消息从备用队列移动到实际队列。因此,实现了使用MSMQ绑定停止IIS托管WCF服务的行为

答案 2 :(得分:0)

停止“Net.Msmq侦听器适配器”Windows服务和“Windows进程激活服务”将阻止消息被拉出队列。重新启动服务将导致消息再次从队列中提取。我是手动执行此操作,而不是通过其他应用程序执行此操作,但我认为您也可以通过其他应用程序执行此操作。我还没有完全测试过,但这样的事情可能会起作用:

    Dictionary<string,List<string>> runningDependentServices = new Dictionary<string,List<string>>();
    private void StartMsmqBinding()
    {
        StartService("WAS");
        StartService("NetMsmqActivator");
    }
    private void StopMsmqBinding()
    {
        StopService("NetMsmqActivator");
        StopService("WAS");
    }
    private void StartService(string serviceName)
    {
        List<string> previouslyRunningServices = null;
        var sc = new ServiceController();
        sc.ServiceName = serviceName;
        if (runningDependentServices.ContainsKey(serviceName))
        {
            previouslyRunningServices = runningDependentServices[serviceName];
        }
        try
        {
            sc.Start();
            sc.WaitForStatus(ServiceControllerStatus.Running);
            if(previouslyRunningServices != null)
            {
                previouslyRunningServices.ForEach(a =>
                {
                    var serviceController = new System.ServiceProcess.ServiceController() { ServiceName = a };
                    serviceController.Start();
                    serviceController.WaitForStatus(ServiceControllerStatus.Running);
                });
            }

        }
        catch (InvalidOperationException)
        {
        }
    }
    private void StopService(string serviceName)
    {
        var sc = new System.ServiceProcess.ServiceController() { ServiceName = serviceName };
        runningDependentServices[serviceName] = sc.DependentServices.Where(a => a.Status == System.ServiceProcess.ServiceControllerStatus.Running).Select(a => a.ServiceName).ToList();
        if (sc.CanStop)
        {
            try
            {
                sc.Stop();
                sc.WaitForStatus(ServiceControllerStatus.Stopped);
            }
            catch (InvalidOperationException)
            {
            }
        }
    }

我认为类似的方法适用于Net.Tcp绑定。在这种情况下,您可能必须停止“Net.Tcp侦听器适配器”Windows服务(ServiceName:“NetTcpActivator”)和“Windows进程激活服务”。