ASP.NET 静态方法和线程安全中实例化正则表达式



取了以下类,它是 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));
    }
}

有人会为我投下更知识渊博的光芒吗?

静态构造函数保证只运行一次,所以你的第一个代码段应该没问题。

从 ECMA C# 规范的第 17.11 节:

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

为了提高安全性,我还会定义一个无参数构造函数。此外,使用 .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;

请参阅此页面,其中包含更多说明。

最新更新