【发布时间】:2019-07-20 08:02:34
【问题描述】:
我正在尝试了解 AsyncLock 的工作原理。
首先,这里有一个sn-p来证明它确实有效:
var l = new AsyncLock();
var tasks = new List<Task>();
while (true)
{
Console.ReadLine();
var i = tasks.Count + 1;
tasks.Add(Task.Run(async () =>
{
Console.WriteLine($"[{i}] Acquiring lock ...");
using (await l.LockAsync())
{
Console.WriteLine($"[{i}] Lock acquired");
await Task.Delay(-1);
}
}));
}
“工作”是指您可以运行任意数量的任务(按 Enter 键)并且线程数不会增加。如果您将其替换为传统的lock,您会看到新线程已启动,这是我们尽量避免的。
但是您在源代码中看到的第一件事是...lock
有人可以解释一下这是如何工作的,为什么它不会阻塞,以及我在这里遗漏了什么?
【问题讨论】:
-
这个问题有点不清楚,上面的代码行不行,能不能展示下行得通的代码
-
是的,它有效,但我不明白为什么。
-
“作品”是指它重用线程。但是
lock关键字应该阻塞线程(在同一个例子中很容易证明这一点)。 -
"re-uses threads" 无关紧要,
Task不等于线程。然而,更准确地说,“lock语句获取给定对象的互斥锁,执行语句块,然后释放锁。当持有锁时,持有锁的线程可以再次获取和释放锁。任何其他线程都被阻止获取锁并等待直到锁被释放。" -
是的,任务被映射到线程,但是由于它们都试图获取相同的锁,所有调度程序的线程都应该被阻塞,每个新任务应该在延迟后启动一个新线程。我刚刚尝试过,对于简单的锁定操作来说确实如此。但由于某种原因,
AsyncLock内部的锁表现不同,或者我错过了一些东西。
标签: c# asynchronous async-await locking task-parallel-library