c# WebService杀死了它所拥有的Singleton

本文关键字:拥有 Singleton WebService | 更新日期: 2023-09-27 18:10:42

我有一个WebService,它拥有一个Singleton:

public class WebService
{
    private static Singleton _singleton = Singleton.Instance;
    public void DoSomeJob(object jobObj) {
        _singleton.QueueJob(jobObj);
    }
}

. .和Singleton,它应该是线程安全的。

public static Singleton Instance
{
    get
    {
        lock (_syncRoot)
        {
            if (_instance == null)
                _instance = new Singleton();
            return _instance;
            }
        }
    }
}

我想用这种方式实现的是,每个调用我的WebService的客户端都将其对象提供给同一个单例实例。同样,这个单例模式除了将对象排队并在计时器滴答时处理它之外,实际上并没有做更多的事情。

我面临的问题(现在仍然是)是,每次WebService终止时,Singleton都会被杀死。然而,我不确定这种情况是否发生,因为Singleton的所有者正在被销毁,或者由于应用程序池设置给出的某种原因。我试图使应用程序池"总是运行"answers"暂停"当空闲时,而不是"按需"answers"终止"-没有成功:-/

为什么Singleton每次都被杀掉?如何在WebService执行之间保持Singleton的实例存活?

c# WebService杀死了它所拥有的Singleton

为什么Singleton每次都被杀掉?

你需要了解WCF是如何管理服务实例化的,才能理解为什么会这样。默认情况下,WCF将通过启用会话的绑定为每个客户端创建一个新的服务实例,如果不支持会话,则为每个调用创建一个新的服务实例。

这意味着被分配处理客户端调用的服务实例将把你的单例实例加载到内存中。然而,当客户端会话或单独调用(不支持会话)完成时,实例将被卸载,这意味着您的单例也将被卸载。

如何在WebService和WebService之间保持Singleton的实例存活死刑?

有两种方法:

  1. 摆脱你的单例。使用一个后备数据存储来跨多个客户机调用维护您的状态。
  2. 通过在服务实现声明中设置InstanceContextMode=InstanceContxtMode.Single来使用单例服务实例。

在这两个选项中,我会选择选项1。这是因为单例服务实例通常是一种反模式,因为它们不能伸缩,只有在没有其他选择时才应该使用。

…考虑将排队功能实现到外部组件,例如Windows服务,但为了简单起见降低了复杂性,我想在网络服务

好的,这就是我认为你问题的根源所在。关于分布式系统有一个共同的信念,可以表述如下:

  • 简单=组件少,和
  • Complex =更多组件

我将把这个信念修改为:

  • Simple =简单组件,和
  • Complex =复杂组件

在我看来,你决定嵌入你的定时器/排队需求到你的web服务自动使你的组件复杂。

我认为拆分从队列读取的组件到另一个组件正是你需要做的!

如果这让你望而生畏,那么我强烈建议你使用topshelf来管理你的windows服务,这是一个免费的框架,它使服务的创建和部署非常简单。