如何使这个C#类单身,线程安全 [英] how to make this c# class a singleton, thread safe

查看:106
本文介绍了如何使这个C#类单身,线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此​​,这里就是我想要做的:

So here's what i'm trying to do :

public static class MyClass
{

   private Dictionary<string,IDisposable> dict = null;

   static MyClass()
   {
         dict = new Dictionary<string,IDisposable>();

         // 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的项目是一个昂贵的远程连接,我准备开,我想打开它只有一次)

I basically want to have a single instance of this class which will initialize the dictionary only once (the IDisposable item is an expensive remote connection i'm opening and i want to open it only once )

这个类将被用于不同的asp.net页面。所以我想这是线程安全的单例。我想在初始化静态构造函数的字典将使其只能被调用一次,是线程安全的,不知道为什么,我不断收到错误。任何想法?

This class will be used by different asp.net pages. So i want it to be thread safe and singleton. I'm thinking initializing the dictionary in the static constructor will make it only be called once and is thread safe, not sure why i keep getting errors. Any ideas?

推荐答案

我同意@Leonardo加西亚克雷斯波的评论。从我所看到这里,你只写了字典中的静态构造函数,这将只能在每个应用程序域调用一次。一切是一个读取和通用词典支持多个阅读器如果集合不被修改。问题可能只能躺在那个正在被调用的code。它也必须是线程安全的。或者,你可以使用相关的锁另一个字典,并锁定相应的锁,这样你只能调用一个非线程安全的情况下的时间。

I agree with @Leonardo Garcia Crespo's comment. From what I see here, you only write to the dictionary in the static constructor, which will only be called once per app domain. Everything else is a read and the generic dictionary supports multiple readers if the collection isn't modified. The problem could only lie in the code that's being invoked. It also needs to be thread-safe. Alternatively, you could use another dictionary of associated locks and lock the corresponding lock so that you can only call one non-thread-safe instance at a time.

public static class MyClass
{
    public static Dictionary<string,SomeDisposableClass> dict = null;
    public static Dictionary<string,object> locks = null;

    static MyClass()
    {
         // populate the dictionary 
         locks = new Dictionary<string,object>();
         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模式,但如果你只有一个静态方法,它可能是没有必要的。我会注意,这将是可怕的,以解决为使用这个类的任何code。

You could also use a Singleton pattern, but if you only have the one static method that's probably not necessary. I will note that this will be horrible to work around for any code that uses this class.

和,是的,我知道,这将是单线程的,如果所谓的1000次相同的值名称。如果这是被调用的方法不是线程安全的,不过,这是最好的,你可以做。这样一来,至少可以有多个线程同时运行为名称不同的值,因为它们锁定不同的对象。

And, yes, I know that it will be single threaded if called 1000 times with the same value for name. If the method that's being called isn't thread-safe, though, that's the best you can do. This way, at least, you can have multiple threads operating for different values of name at the same time since they lock on different objects.

这篇关于如何使这个C#类单身,线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆