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) 今天我和Lazy一起玩,<T>发现了一个有趣的案例(在我看来).
http://msdn.microsoft.com/en-us/library/system.threading.lazythreadsafetymode.aspx
PublicationOnly:
当多个线程尝试同时初始化Lazy实例时,允许所有线程运行初始化方法...将丢弃由竞争线程创建的任何T实例.
如果我们查看Lazy <T>.LazyInitValue()的代码,我们会发现没有检查IDisposable实现,并且这里的resoruces可能会泄漏:
case LazyThreadSafetyMode.PublicationOnly:
boxed = this.CreateValue();
if (Interlocked.CompareExchange(ref this.m_boxed, boxed, null) != null)
{
//* boxed.Dispose(); -> see below.
boxed = (Boxed<T>) this.m_boxed;
}
break;
Run Code Online (Sandbox Code Playgroud)截至目前,确保仅创建实例的唯一方法是使用LazyThreadSafetyMode.ExceptionAndPublication.
所以我有两个问题:
如果正确的假设为什么不在这种情况下检查IDisposable并在Boxed上实现Dispose(),<T>以便它将处理委托给Boxed实例,T如果它实现IDisposable或以某种不同的方式:
class Boxed<T>
{
internal T m_value;
void Dispose()
{
if (m_value is IDisposable)
{ ((IDisposable) m_value).Dispose(); }
}
}
Run Code Online (Sandbox Code Playgroud)