【问题标题】:How can we create a Singleton Instance for a Window?我们如何为一个窗口创建一个单例实例?
【发布时间】:2013-04-17 09:16:22
【问题描述】:

我已经搜索了在 WPF 中为窗口创建单例对象。

public static Test DefInstance
{
    get
    {
        if (formDefInstance == null)  // formDefInstance.IsDisposed
        {
            initializingDefInstance = true;
            formDefInstance = new cas18();
            initializingDefInstance = false;
        }
        return formDefInstance;
    }
    set { formDefInstance = value; }
}

但是forDefInstance.IsDisposed 不起作用并引发错误。

对此有什么想法吗?

【问题讨论】:

  • 没有理由对这个问题投反对票。从代码示例中可以清楚地看出他想要做什么:他希望窗口只打开一次,但还想检测窗口是否关闭。然后应该可以再次打开它,但屏幕上绝不应该同时出现两个这样的窗口。我实际上认为这是一个非常有趣的问题!
  • @ThorstenDittmar:我不是那个投反对票的人,但是写“......不起作用并抛出错误”没有包括错误消息就像要求成为被否决。
  • @Heinzi 虽然这个问题并不完整,但我认为它不值得一票否决。 @OP 请添加错误信息。
  • Window 类 (WPF) 中没有 IsDisposed 属性。您是在谈论 winforms 吗?
  • @ThorstenDittmar/ken2k:我怀疑这是正确的 - 我会说这是一个合理的理由来否决这个问题,至少在 OP 没有编辑或澄清的情况下。 (我没有对自己投反对票,但我明白人们为什么会投反对票。)

标签: c# wpf c#-4.0 singleton


【解决方案1】:

我认为每个人都应该看看 Jon Skeet 的 C# In Depth 站点。如果只是为了阅读并永久地在他们的大脑中燃烧单例模式 a-la C#。

http://csharpindepth.com/Articles/General/Singleton.aspx

在你的场景中,尝试实现这个(线程安全,非惰性):

public sealed class DefInstance
{
  private static readonly DefInstance instance = new DefInstance();
  static DefInstance()
  {
  }

  private DefInstance()
  {
  }

  public static DefInstance Instance
  {
    get
    {
      return instance;
    }
   }
} 

该站点中还有Lazy<T> 实现和该模式的各种其他实现。

【讨论】:

    【解决方案2】:

    我不知道这是否是你想要做的,但它对我有用:

    private static MyWindow _defInstance;
    public static MyWindow DefInstance
    {
        get
        {
            if (null == _defInstance)
            {
                _defInstance = new MyWindow();
            }
            return _defInstance;
        }
     }
    

    在 MyWindow 代码中:

    protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
    {
        this.Visibility = Visibility.Hidden;
        e.Cancel = true;
    }
    

    使用它:

    DefInstance.Show();
    

    然后,只显示一个窗口,您使用窗口的一个实例。

    【讨论】:

      【解决方案3】:

      您可以通过实现以下方法来实现这一点

      private static volatile DefInstance instance;
      private static object syncRoot = new Object();
      
      private DefInstance() {}
      
      public static DefInstance Instance
      {
         get 
         {
            if (instance == null) 
            {
               lock (syncRoot) 
               {
                  if (instance == null) 
                     instance = new DefInstance();
               }
            }
      
            return instance;
         }
      }
      

      【讨论】:

      • 哇!为什么易挥发?单例的目标是创建一次并防止后续实例创建。 volatile 关键字可以创建一个或多个后续实例并将其分配给DefInstance。请改用readonly
      • 变量被声明为 volatile 以确保在可以访问实例变量之前完成对实例变量的赋值
      • private static readonly DefInstance instance = new DefInstance() 确保线程安全和可访问性,并防止后续写入。 volatile 没有。
      • 请阅读这个问题的答案然后你就会知道为什么我提到使用 volatile..stackoverflow.com/questions/1964731/…
      • 我在示例中提到了双重检查锁定方法。有关此概念的更多信息,您可以参考此文档en.wikipedia.org/wiki/Double-checked_locking
      猜你喜欢
      • 1970-01-01
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      相关资源
      最近更新 更多