懒惰ExecutionAndPublication - 例如,可能导致死锁

对于LazyThreadSafetyMode的文档指出使用值ExecutionAndPublication可能会导致死锁如果初始化方法(或默认的构造函数,如果没有初始化方法)使用锁在内部。 我想获得一个更好地了解使用此值时可能导致死锁的例子。 在我使用这个值,我初始化的ChannelFactory。 使用任何内部锁(审查与反射类),我无法看到的ChannelFactory的构造函数,所以我相信这种情况下不适合的可能死锁的情况,不过我很好奇,什么情况下可能会导致死锁,以及是否有可能是一个可能的死锁初始化的ChannelFactory。

因此,要总结,我的问题是:

  1. 是否有可能导致死锁初始化使用ExecutionAndPublication的的ChannelFactory?
  2. 什么是一些可能的方式来引起死锁初始化使用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(); } }

--------------解决方案-------------

  1. 它作为记录 - 如果它不使用任何锁,这种用法不能引起任何死锁。
  2. 试想一下,您有被从数据库中读取初始化一个懒惰的价值,但你要确保只有一个线程访问DB在任何时刻。 如果您有访问数据库的其他代码,你​​可以有一个僵局。 考虑下面的代码:

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
}
}
}

Init()从DB中读取,因此具有使用锁。 UpdateDb()写入到数据库,因此它需要锁定过了,因为Lazy在这种情况下使用一个锁内部太,它会导致死锁。

在这种情况下,这将是很容易由移动接入到固定死锁lazyInt.ValueUpdateDb()锁声明外,但它可能无法在其他情况下,这样琐碎(或明显)。

分类:C# 时间:2015-03-15 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.420 (s). 10 q(s)