C# ASP .NET MVC 3 单例构造函数调用两次

发布于 2025-01-05 07:33:30 字数 610 浏览 3 评论 0原文

我有一个由三个项目组成的项目,

  1. WCF 服务
  2. Asp.net MVC 3 应用程序
  3. 类库。

类库中的是我的单例,我是这样制作的;

public sealed class Singleton
{
    public static Singleton Instance { get; set; }

    private Singleton()
    {

    }

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

问题是,我在构造函数中放置了一个 Debug.WriteLine,并且它被调用了两次。
我想做的是使用 mvc 3 应用程序和 WCF 服务中的单例,但它们创建不同的实例。为什么?

编辑:我早些时候尝试过一个tracesafe单例。这没有什么区别。

I have a project consisting of three projects,

  1. WCF service
  2. Asp.net MVC 3 application
  3. Class library.

The one in the class library is my singleton, which I have made like this;

public sealed class Singleton
{
    public static Singleton Instance { get; set; }

    private Singleton()
    {

    }

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

The thing is, I put a Debug.WriteLinein the constructor, and it gets called twice.
What I am trying to do is use the singleton from the mvc 3 application and from the WCF service, but they make different instances. Why?

EDIT: I tried a treadsafe singleton earlier. It made no difference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

甜柠檬 2025-01-12 07:33:30

这里可能会发生一些事情。

最有可能的是您的 MVC 应用程序和 WCF 服务运行在不同的 AppDomain 中。如果是这种情况,代码将不可能“共享”同一实例。

另一种不太可能的原因是,由于您的代码不是线程安全的,因此创建了多个实例。如果单例构造函数需要很长时间才能返回,那么这可能就是问题所在。由于您使用 MVC3,我将假设 .Net 4,在这种情况下 Lazy 类 是你的朋友:

private static readonly Lazy<Singleton> _singleton = new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return _singleton.Value; } }

There's a couple of things that could be going on here.

The most likely is that your MVC application and your WCF service are running in different AppDomains. It will be impossible for the code to 'share' the same instance if this is the case.

An alternative and less likely cause, is that because your code is not thread safe multiple instances are created. If the Singleton constructor takes a long time to return then this could be the issue. Since your using MVC3, I'll assume .Net 4, in which case the Lazy class is your friend:

private static readonly Lazy<Singleton> _singleton = new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return _singleton.Value; } }
乜一 2025-01-12 07:33:30

我猜你的实现不是线程安全的。查看文章:在 C# 中实现单例

这里有一个线程安全的示例: (还有很多其他方法可以做到这一点,更复杂也更安全,这只是一个参考......)

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}

I guess your implementation is not thread safe. check the article: Implementing Singleton in C#

here a thread-safe example: (there are many other ways to do this, more complex and safer, this is just a reference...)

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}
情绪 2025-01-12 07:33:30

我没有 WCF 的经验,但也许你应该实现一个线程安全的单例,请参阅: http: //www.yoda.arachsys.com/csharp/singleton.html

I have no experience with WCF, but maybe you should implement a thread safe singleton, see: http://www.yoda.arachsys.com/csharp/singleton.html

梦忆晨望 2025-01-12 07:33:30

如果 WCF 服务作为单独的应用程序运行,它将拥有自己的单例实例,因为这两个应用程序不共享内存。

WCF 服务是否在与 MVC 应用程序不同的 IP 地址/端口号上运行?

If the WCF Service is running as a separate application, it will have it's own instance of the singleton as the two applications do not share memory.

Does the WCF Service run on a different IP Address/port number to the MVC application?

短叹 2025-01-12 07:33:30

中使用惰性模式

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
} 

您可以在.Net 4.0源 : http://csharpindepth.com/Articles/General /Singleton.aspx

You can use the lazy pattern in .Net 4.0

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
} 

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

离鸿 2025-01-12 07:33:30

首先,您发布的确切代码不起作用。它在语法上不正确(花括号不平衡),并且有两个公共 Singleton.Instance 成员。我假设您的原始代码是这样的:

public sealed class Singleton
{
    private static Singleton _instance { get; set; }

    private Singleton()
    {

    }

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

问题可能与多线程环境有关。也就是说,当一个线程调用 new Singleton() 时,另一个线程尝试获取 Singleton.Instance,而该实例又调用另一个 new Singleton()

您应该在那里使用双重检查锁定:

public sealed class Singleton
{
    private static Singleton _instance { get; set; }

    private Singleton()
    {

    }

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

或者更简单,

public sealed class Singleton
{
    public static readonly Singleton _instance = new Singleton();

    private Singleton()
    {

    }
}

First, your exact code as posted is not working. It is not syntactically correct (the curly braces are not balanced), and there are two public Singleton.Instance members. I assume your original code was like that:

public sealed class Singleton
{
    private static Singleton _instance { get; set; }

    private Singleton()
    {

    }

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

The problem is probably related to a multi-threading environment. That is, while one of threads is calling new Singleton(), another tried to get Singleton.Instance, which, in turn, called another new Singleton().

You should either use double-checked locking there:

public sealed class Singleton
{
    private static Singleton _instance { get; set; }

    private Singleton()
    {

    }

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

or, much easier,

public sealed class Singleton
{
    public static readonly Singleton _instance = new Singleton();

    private Singleton()
    {

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文