gpt4 book ai didi

c# - Lazy ExecutionAndPublication - 可能导致死锁的示例

转载 作者:可可西里 更新时间:2023-11-01 08:10:26 26 4
gpt4 key购买 nike

LazyThreadSafetyMode 的文档声明如果初始化方法(或默认构造函数,如果没有初始化方法)在内部使用锁,则使用值 ExecutionAndPublication 可能会导致死锁。我试图更好地理解使用此值时可能导致死锁的示例。在我使用这个值时,我正在初始化一个 ChannelFactory .我看不到 ChannelFactory 的构造函数使用任何内部锁(使用 Reflector 查看类),所以我相信这种情况不符合可能的死锁情况,但我很好奇什么情况会导致死锁以及是否可能死锁初始化 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. 假设您有一个通过从数据库中读取来初始化的惰性值,但您希望确保在任何时刻只有一个线程正在访问该数据库。如果您有其他访问数据库的代码,则可能会出现死锁。考虑以下代码:
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() 从数据库中读取,所以它必须使用锁。 UpdateDb() 写入数据库,因此它也需要锁,并且由于 Lazy 在这种情况下也在内部使用锁,因此会导致死锁。

在这种情况下,通过将对 UpdateDb() 中的 lazyInt.Value 的访问移到 lock 语句之外,可以很容易地修复死锁,但它可能不会在其他情况下如此微不足道(或明显)。

关于c# - Lazy<T> ExecutionAndPublication - 可能导致死锁的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6164434/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com