dug*_*gas 13 .net c# deadlock lazythreadsafetymode
LazyThreadSafetyMode的文档指出,如果初始化方法(或默认构造函数,如果没有初始化方法)在内部使用锁,则使用值ExecutionAndPublication可能会导致死锁.我试图更好地理解使用此值时可能导致死锁的示例.在我使用这个值时,我正在初始化一个ChannelFactory.我看不到ChannelFactory的构造函数使用任何内部锁(使用Reflector查看类),所以我认为这种情况不适合可能的死锁情况,但我很好奇什么情况可能导致死锁以及是否有可能死锁初始化ChannelFactory.
总而言之,我的问题是:
是否可能导致使用ExecutionAndPublication初始化ChannelFactory的死锁?
使用ExecutionAndPublication导致死锁初始化其他对象有哪些可能的方法?
假设您有以下代码:
class x
{
static Lazy<ChannelFactory<ISomeChannel>> lcf =
new Lazy<ChannelFactory<ISomeChannel>>(
() => new ChannelFactory<ISomeChannel>("someEndPointConfig"),
LazyThreadSafetyMode.ExecutionAndPublication
);
public static ISomeChannel Create()
{
return lcf.Value.CreateChannel();
}
}
Run Code Online (Sandbox Code Playgroud)
svi*_*ick 10
void Main()
{
Task otherThread = Task.Factory.StartNew(() => UpdateDb(43));
Thread.Sleep(100);
Console.WriteLine(lazyInt.Value);
}
static object l = new object();
Lazy<int> lazyInt = new Lazy<int>(Init, LazyThreadSafetyMode.ExecutionAndPublication);
static int Init()
{
lock(l)
{
return ReadFromDb();
}
}
void UpdateDb(int newValue)
{
lock(l)
{
// to make sure deadlock occurs every time
Thread.Sleep(1000);
if (newValue != lazyInt.Value)
{
// some code that requires the lock
}
}
}
Run Code Online (Sandbox Code Playgroud)
Init()从DB读取,因此必须使用锁.UpdateDb()写入数据库,因此它也需要锁定,并且由于Lazy在这种情况下也在内部使用锁定,因此会导致死锁.
在这种情况下,它会很容易接入移动解决僵局lazyInt.Value的UpdateDb()lock语句之外,但它可能不会在其他情况下,如此微不足道的(或明显).