【发布时间】:2020-06-06 11:59:39
【问题描述】:
我有一个非常简单的控制台应用程序来测试 SemaphoreSlim 的功能。
class Program
{
private static readonly ConcurrentDictionary<string, SemaphoreSlim> _locks = new ConcurrentDictionary<string, SemaphoreSlim>();
private static int _counter = 0;
static async Task Main(string[] args)
{
var tasks = new List<Task>();
for (var i = 1; i <= 1000; i++)
{
tasks.Add(Task.Factory.StartNew(async () => await IncCountWithDictLock("10"))); ;
}
await Task.WhenAll(tasks);
Console.WriteLine(_counter);
}
public static async Task IncCountWithDictLock(string userId)
{
_locks.TryAdd(userId, new SemaphoreSlim(1, 1));
var l = _locks[userId];
var acuireLockRequire = await l.WaitAsync(TimeSpan.FromSeconds(5));
if (acuireLockRequire)
{
_counter++;
l.Release();
}
else
{
Console.WriteLine("unable acquire the lock");
}
}
}
我希望计数器的结果是 1000,而它是随机的。我在使用 SemaphoreSlim 时是否遗漏了什么?
【问题讨论】:
-
Task.Factory.StartNew中的 lambda 实际上并没有被等待。见stackoverflow.com/questions/30819847/…。尝试为StartNew拨打Unwrap(),看看会发生什么。 -
tasks.Add(IncCountWithDictLock("10"))怎么样? -
@Clemens 很有趣。它会自动运行
Task吗? -
从 IncCountWithDictLock 返回的任务将在 WhenAll 中等待。