1

我在 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

3 回答 3

3

创建实例的MyService方式和时间由 WCF 功能控制,例如InstanceContextMode(它是 的一部分ServiceBehaviourAttribute):

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

Sessions、Instancing 和 Concurrency中也有一些值得阅读的内容。


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

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

于 2013-10-22T06:53:04.437 回答
1

你用一个类型启动你的服务主机。

_serviceHost = new ServiceHost(typeof(MyService));    

这意味着服务主机必须创建一个实例。它将使用其他答案中提到的参数来执行此操作。如果您不希望服务主机为您创建实例,您可以给它一个实例以供自己使用:

_serviceHost = new ServiceHost(new MyService());    

服务主机将使用此实例来处理所有调用。不过,您可能希望先将其放入变量中。

于 2013-10-22T07:09:56.080 回答
0

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

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

于 2013-10-22T07:00:49.533 回答