如何使这个c#类成为单例,线程安全

所以这就是我要做的事情:

public static class MyClass { private Dictionary dict = null; static MyClass() { dict = new Dictionary(); // i fill up the dictionary in a loop here // } public static UseDictionary(string name) { var obj = dict[name] obj.DoSomeAction(); } } static void Main(string[] args) { Parallel.For(0, 1000, x => { // assuming 'name' does exist in the dictionary MyClass.UseDictionary("name"); // randomly throws null reference errors }); } 

我基本上想要这个类的一个实例,它只会初始化一次字典(IDisposable项目是一个昂贵的远程连接,我打开它,我想只打开一次)

该类将由不同的asp.net页面使用。 所以我希望它是线程安全和单身。 我想在静态构造函数中初始化字典将使它只被调用一次并且是线程安全的,不知道为什么我一直收到错误。 有任何想法吗?

我同意@Leonardo Garcia Crespo的评论。 从我在这里看到的,你只能在静态构造函数中写入字典,每个应用程序域只会调用一次。 其他所有内容都是读取,如果未修改集合,则通用字典支持多个读取器。 问题可能只在于被调用的代码。 它还需要是线程安全的。 或者,您可以使用另一个关联锁的字典并锁定相应的锁,以便您一次只能调用一个非线程安全的实例。

 public static class MyClass { public static Dictionary dict = null; public static Dictionary locks = null; static MyClass() { // populate the dictionary locks = new Dictionary(); foreach (var key in dict.Keys) { locks[key] = new object(); } } public static void UseDictionary( string name ) { var obj = dict[name]; var sync = locks[name]; lock(sync) { obj.DoSomething(); } } } 

您也可以使用Singleton模式,但是如果您只有一个可能不需要的静态方法。 我会注意到,对于使用此类的任何代码来说,这将是非常糟糕的。

并且,是的,我知道如果使用相同的name值调用1000次,它将是单线程的。 但是,如果被调用的方法不是线程安全的,那么这是你能做到的最好的方法。 这样,至少,您可以让多个线程同时针对不同的name值进行操作,因为它们会锁定不同的对象。

以下代码应该是线程安全的,因为.NET保证静态字段初始化程序的线程安全

 private static readonly Dictionary dict = CreateAndInitializeDictionary(); private static Dictionary CreateAndInitializeDictionary() { var d = new Dictionary(); .... // here add items return d; } 

在再次检查您的代码之后,我意识到您的实现也是线程安全的。 问题应该在DoSomething()某个地方:)

您可以在类上使用Synchronization属性。 这就是我为其中一门课所做的。 我包括了评论,因为他们解释了这种情况。

 [Synchronization] public class IprServerController : ContextBoundObject { // We need to worry about things like a user deleting a route at the same time that another user is starting one. // So, instead of trying to lock appropriately throughout the class, we can lock declaratively, by using the // Synchronization attribute and deriving from ContextBoundObject. Now only one thread can execute methods on // this class at a time. 

请看这里http://www.codeproject.com/Articles/14026/Generic-Singleton-Pattern-using-Reflection-in-C

对不起,:’(通往地狱的道路充满了善意

我只想提供另一个简单的选项而不需要详细介绍

我也遇到问题之后的时间,我发布多个网络服务,所以多单身最终创建我自己的版本。

这真的有用,我有大约50个内部应用程序和一些外部提供商使用它。

总结之后关于单例模式的检查想法和在c#中完成的不同示例我得出的结论是一个好的实现基于内部类创建一个实例是保证调用构造函数一次完成虽然单例clas是从许multithreading调用的,所以只有一个实例

在vb.net简化

 Public NotInheritable Class ServiceProxySingleton Private Sub New() End Sub Public Shared Function GetInstance() As ServiceProxySingleton Return NestedSingletonService._instance End Function ' Internal class Class NestedSingletonService Friend Shared ReadOnly _instance As [SingletonClass] = New [SingletonClass]() Shared Sub New() End Sub End Class End Class