C# 存在lock语句时,字段初始化在静态类中不起作用,这是一个奇怪的问题
我在asp.net mvc应用程序中使用了以下静态类(为了清晰起见,进行了简化)C# 存在lock语句时,字段初始化在静态类中不起作用,这是一个奇怪的问题,c#,locking,C#,Locking,我在asp.net mvc应用程序中使用了以下静态类(为了清晰起见,进行了简化) public static class GObjContextHelper { private static readonly object _lock = new object(); public static GObjContext GetObjContext() { Trace.TraceInformation("_lock: " + _lock); //lock (_lock
public static class GObjContextHelper
{
private static readonly object _lock = new object();
public static GObjContext GetObjContext()
{
Trace.TraceInformation("_lock: " + _lock);
//lock (_lock)
//{
//Trace.TraceInformation("exclusive section");
//}
return null;
}
....
}
除非未注释锁块,否则它工作得非常好。
此时_lock字段停止初始化-_lock为空,可通过调试器或跟踪信息进行验证。
事实上,一旦存在锁块,任何字段的内联和使用静态构造函数的初始化都会停止工作。
更奇怪的是,这只发生在这个特殊的类中。我无法在应用程序中的任何其他静态类中复制它
我有一种感觉,我错过了一些令人尴尬的琐事
[编辑]
事实证明(我应该首先提供一个更完整的示例。)其中一个字段变量在内部引用了GObjContextHelper.GetObjContext()。修复此循环引用后,一切正常
我仍然希望解释一下静态类初始化过程中会发生什么,其中字段变量是在构造函数中引用上述静态类的对象。以及为什么lock语句对变量的初始化顺序有这样的影响
一个更详细的例子:
public static class GObjContextHelper
{
private static TestService testService = new TestService();
private static readonly object _lock = new object();
public static GObjContext GetObjContext()
{
Trace.TraceInformation("_lock: " + _lock);
// _lock is properly initialized if this lock block is commented out.
// otherwise _lock is null
//lock (_lock)
//{
//}
return null;
}
public static object Account { get { return testService.GetCurrentAccount(); } }
}
public class TestService
{
GObjContext context;
public AccountService()
{
context = GObjContextHelper.GetObjContext();
}
public object GetCurrentAccount()
{
return null;
}
}
您完全可以通过以下方式停止担心:
public static class GObjContextHelper
{
private static object _lock;
public static GObjContext GetObjContext()
{
Trace.TraceInformation("_lock: " + _lock);
lock (GetLockObject())
{
Trace.TraceInformation("exclusive section");
}
return null;
}
private static object GetLockObject()
{
if (_lock == null)
{
_lock = new object();
}
return _lock;
}
....
}
您完全可以通过以下方式停止担心:
public static class GObjContextHelper
{
private static object _lock;
public static GObjContext GetObjContext()
{
Trace.TraceInformation("_lock: " + _lock);
lock (GetLockObject())
{
Trace.TraceInformation("exclusive section");
}
return null;
}
private static object GetLockObject()
{
if (_lock == null)
{
_lock = new object();
}
return _lock;
}
....
}
如果要对静态字段进行确定性初始化,则需要使用静态构造函数:
public static class GObjContextHelper
{
private static readonly object _lock;
static GObjContextHelper()
{
_lock = new object();
}
}
您还可以通过指定静态构造函数来强制字段初始化。这会告诉c#编译器,您的类型不会被标记为beforefieldinit CIL属性
public static class GObjContextHelper
{
private static readonly object _lock = new object();
static GObjContextHelper()
{
}
}
如果要对静态字段进行确定性初始化,则需要使用静态构造函数:
public static class GObjContextHelper
{
private static readonly object _lock;
static GObjContextHelper()
{
_lock = new object();
}
}
您还可以通过指定静态构造函数来强制字段初始化。这会告诉c#编译器,您的类型不会被标记为beforefieldinit CIL属性
public static class GObjContextHelper
{
private static readonly object _lock = new object();
static GObjContextHelper()
{
}
}
我认为C#中的静态字段初始化顺序是不确定的,所以这可能是问题所在。我不知道。这个独立的代码片段在VS2010中对我很有用。您何时/何处调用GetObjContext?从另一个静态场?例如,私有静态GObjContext=GetObjContext()代码>?
GObjContextHelper
是分部类吗?另一个源文件中的静态字段初始值设定项是否使用了GetObjContext
方法?我已经更新了这个问题。很抱歉之前没有提供更详细的示例。我认为C#中的静态字段初始化顺序是不确定的,所以这可能就是问题所在。我不知道。这个独立的代码片段在VS2010中对我很有用。您何时/何处调用GetObjContext?从另一个静态场?例如,私有静态GObjContext=GetObjContext()代码>?GObjContextHelper
是分部类吗?另一个源文件中的静态字段初始值设定项是否使用了GetObjContext
方法?我已经更新了这个问题。抱歉,之前没有提供更详细的示例。您的示例中有一个输入错误,您应该锁定返回的对象,而不是方法groupI更新了问题。抱歉,之前没有提供更详细的示例。您的示例中有一个输入错误,您应该锁定返回的对象,而不是方法groupI更新了问题。很抱歉之前没有提供更详细的示例。我已经更新了问题。很抱歉之前没有提供更详细的示例。我已经更新了问题。很抱歉,之前没有提供更详细的示例。