ASP.NET 在静态方法和线程安全中实例化正则表达式
ASP.NET instantiating regex within a static method and thread safety
采用以下 class,它是 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));
}
}
有人可以为我提供更多知识吗?
static constructor 保证只 运行 一次,所以你的第一个片段应该没问题。
来自 ECMA C# Spec 的第 17.11 节:
The static constructor for a non-generic class executes at most once
in a given application domain. The static constructor for a generic
class declaration executes at most once for each closed constructed
type constructed from the class declaration.
我还会定义一个无参数的构造函数以提高安全性。
此外,使用 .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;
}
}
}
使用 class 时,您将像处理常规静态对象一样处理 Regex
对象 属性:
var regex = RegexUtility.RadioButton;
请参阅 this page 以及更多说明。
采用以下 class,它是 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));
}
}
有人可以为我提供更多知识吗?
static constructor 保证只 运行 一次,所以你的第一个片段应该没问题。
来自 ECMA C# Spec 的第 17.11 节:
The static constructor for a non-generic class executes at most once in a given application domain. The static constructor for a generic class declaration executes at most once for each closed constructed type constructed from the class declaration.
我还会定义一个无参数的构造函数以提高安全性。
此外,使用 .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;
}
}
}
使用 class 时,您将像处理常规静态对象一样处理 Regex
对象 属性:
var regex = RegexUtility.RadioButton;
请参阅 this page 以及更多说明。