ASP.NET在静态方法和线程安全性中实例化regex

时间:2015-03-12 09:54:55

标签: c# asp.net regex .net-4.0 thread-safety

采用以下类作为ASP.NET HttpModule的一部分(我知道有关正则表达式和html的内容,但我不能在这个中做出选择):

sealed internal class RegexUtility
{
    public static Regex RadioButton { get; private set; }

    static RegexUtility()
    {
       RadioButton = new Regex(@"<input.*type=.?radio.*?>", RegexOptions.Compiled);
    }
}

我关注此代码的线程安全性。由于正则表达式是只读的,我知道我不必担心它在内存中的修改。我担心实例化本身,但是,我应该将它锁定在构造函数中吗?一个有根据的猜测表明下面的代码是线程安全的。我的想法是两个线程可能会同时尝试并实例化它,因此需要锁定。但是,因为这是静态的,据我所知,IIS应用程序池中只有一个应用程序实例(对吗?),那么也许我不需要担心它。

sealed internal class RegexUtility
{
    public static Lazy<Regex> RadioButton { get; private set; }

    static RegexUtility()
    {
        RadioButton = new Lazy<Regex>(() => new Regex(@"<input.*type=.?radio.*?>", RegexOptions.Compiled));
    }
}

有人会为我提供更明智的知识吗?

2 个答案:

答案 0 :(得分:1)

static constructor保证只运行一次,因此您的第一个代码段应该没问题。

来自ECMA C# Spec的第17.11节:

  

非泛型类的静态构造函数最多执行一次   在给定的应用程序域中。泛型的静态构造函数   对于每个关闭的构造,类声明最多执行一次   从类声明构造的类型。

答案 1 :(得分:1)

我还定义了一个无参数的构造函数,以提高安全性。 此外,使用.Net 4.0 System.Lazy类型并不是一个坏主意,它保证了线程安全的延迟构造。

    public class RegexUtility
    {
        private static readonly Lazy<RegexUtility> _instance
            = new Lazy<RegexUtility>(() => new RegexUtility());

        private static Lazy<Regex> _radioButton = new Lazy<Regex>(() => new Regex(@"<input.*type=.?radio.*?>"));
        public static Regex RadioButton
        {
            get
            {
                return _radioButton.Value;
            }
        }

        // private to prevent direct instantiation.
        private RegexUtility()
        {
        }

        // accessor for instance
        public static RegexUtility Instance
        {
            get
            {
                return _instance.Value;
            }
        }
    }

使用该类时,您将使用Regex对象,就像它是常规静态属性一样:

   var regex = RegexUtility.RadioButton;

请参阅this page并提供更多解释。