为什么Windows服务会创建服务主机的多个实例

时间:2013-10-22 06:48:40

标签: wcf

我在Windows服务中托管一个简单的WCF服务。 WCF服务本身创建TextWriterTraceListener,它将记录检测数据。

奇怪的是,即使Windows服务没有重新启动,它似乎仍在创建新的日志文件,并且正在将相同的日志条目写入多个文件。

只有在MyService的构造函数被多次触发时,基本上每次客户端连接到服务时,才会发生上述行为。我的未知和希望是它只会创建一个MyServiceBase实例,因此只创建一个MyService实例(每次启动Windows服务)。

当然我可以解决这个问题并检查Trace中添加了多少个侦听器,但我想了解发生了什么。

代码如下:

var ServicesToRun = new ServiceBase[] 
            { 
                new MyServiceBase() 
            };
        ServiceBase.Run(ServicesToRun);

public partial class MyServiceBase : ServiceBase
{
    ServiceHost _serviceHost;

    public MyServiceBase()
    {
        InitializeComponent();
    }


    protected override void OnStart(string[] args)
    {
        _serviceHost = new ServiceHost(typeof(MyService));            
        _serviceHost.Open();

    }

    protected override void OnStop()
    {
        if (_serviceHost != null)
        {
            _serviceHost.Close();
        }
        _serviceHost = null;
    }        
}

 public MyService()
    {         
        _fileListner = new TextWriterTraceListener(string.Format(@"{0}\Trace{1}.log", logDir, DateTime.Now.Ticks));
        Trace.Listeners.Add(_fileListner);
        WriteTraceMessage(string.Format("Service started {0}", DateTime.Now), new Guid("71961817-CB62-410f-AB44-43BFCE246847"));
    }

4 个答案:

答案 0 :(得分:3)

如何以及何时创建MyService的实例由WCF功能控制,例如InstanceContextModeServiceBehaviourAttribute的一部分):

  

使用InstanceContextMode属性指定何时创建新服务对象。由于服务对象不直接连接到通信通道,因此服务对象的生命周期与客户端和服务应用程序之间的通道的生命周期无关。默认值PerSession指示服务应用程序在客户端和服务应用程序之间建立新的通信会话时创建新的服务对象。同一会话中的后续调用由同一对象处理。

Sessions, Instancing and Concurrency中也可以阅读一些内容。


  

我的未知和希望是它只会创建MyServiceBase的一个实例,因此只有MyService的一个实例

但请注意,在OnStart方法中,您没有创建新的MyService对象 - 您将类型传递给ServiceHost,因为主机然后使用WCF属性(或配置)来确定生命周期。

答案 1 :(得分:1)

使用类型启动servicehost。

_serviceHost = new ServiceHost(typeof(MyService));    

这意味着servicehost必须创建一个实例。它将使用其他答案中提到的参数来完成。如果您不希望servicehost为您创建实例,您可以为其自己使用实例:

_serviceHost = new ServiceHost(new MyService());    

servicehost将使用此实例来处理所有调用。您可能希望首先将其放入变量中。

答案 2 :(得分:0)

看看这篇文章 - http://msdn.microsoft.com/en-us/library/ms731193.aspx关于wcf服务的实例化

答案 3 :(得分:0)

默认情况下,实例上下文模式将设置为每个会话。因此,当请求到来时,它将创建一个新的服务实例。如果要为每个调用仅创建一个实例,请设置实例上下文模式=每次调用。如果您只想为整个应用程序创建一个实例,则设置实例上下文模式=单个。

供参考检查此链接: http://wcftutorial.net/Per-Call-Service.aspx