我有一个由三个项目组成的项目,
类库中的那个是我的单例,我这样做了;
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服务中的单例,但它们会生成不同的实例。为什么呢?
答案 0 :(得分:3)
这里可能会发生一些事情。
最有可能的是,您的MVC应用程序和WCF服务正在不同的AppDomain中运行。如果是这种情况,代码将无法“共享”同一个实例。
另一种不太可能的原因是,因为您的代码不是线程安全的,所以创建了多个实例。如果Singleton构造函数需要很长时间才能返回,那么这可能就是问题所在。由于您使用MVC3,我将假设.Net 4,在这种情况下Lazy class是您的朋友:
private static readonly Lazy<Singleton> _singleton = new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return _singleton.Value; } }
答案 1 :(得分:1)
我猜你的实现不是线程安全的。查看文章:Implementing Singleton in 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;
}
}
}
答案 2 :(得分:0)
我没有使用WCF的经验,但也许您应该实现一个线程安全的单例,请参阅:http://www.yoda.arachsys.com/csharp/singleton.html
答案 3 :(得分:0)
如果WCF服务作为单独的应用程序运行,它将拥有它自己的单例实例,因为这两个应用程序不共享内存。
WCF服务是否在与MVC应用程序不同的IP地址/端口号上运行?
答案 4 :(得分:0)
您可以在.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()
{
}
}
答案 5 :(得分:-1)
首先,您发布的确切代码无效。它在语法上不正确(花括号不平衡),并且有两个公共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()
{
}
}
或者,更容易,
{{1}}