由PreApplicationStartMethod
属性修饰的程序集中的类中的方法应在Application_Start
事件触发之前调用。
例如,这是BuildManager
在编译页面,控件或视图时了解哪些程序集(除了Web应用程序中的程序集)之外的方式。
期望指出的方法只被调用一次是很自然的 - 毕竟它是初始化过程的一部分,通常每个应用程序只发生一次。 (我只会提到两次创建数据库的尝试!!)
添加一些跟踪调用后,我发现该方法(有时不总是!)被调用两次。
为了避免这种情况,我在类中添加了一个布尔字段,以防止多次调用:
private static bool initialzed;
public static void Initialize()
if (PreApplicationInit.initialzed == false)
{
// perform the initialization here
// ...
PreApplicationInit.initialzed = true;
}
}
令我惊讶的是,该方法再次被调用了两次。一个明显的怀疑是它被调用在两个不同的线程上(尽管这在初始化代码中有点意义)。 Double-check locking是解决此类问题的明显方法,因此我更改了代码:
private static readonly object SyncRoot = new Object();
private static bool initialzed;
public static void Initialize()
{
if (PreApplicationInit.initialzed == false)
{
lock (PreApplicationInit.SyncRoot)
{
if (PreApplicationInit.initialzed == false)
{
// perform the initialization here
// ...
PreApplicationInit.initialzed = true;
}
}
}
}
真正使这个问题的真正原因是代码是从本机代码调用的。这是跟踪点的$ CALLER:
[Native to Managed Transition]
所以,我的问题很明显,我猜:什么(更重要的原因!)调用一个表示在Application_Start
事件之前调用多次的方法?