【问题标题】:Strange output when using SemaphoreSlim to lock the method使用 SemaphoreSlim 锁定方法时的奇怪输出
【发布时间】: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 中等待。

标签: c# .net .net-core


【解决方案1】:

Task.Factory.StartNew 中的 lambda 实际上并没有被等待。 见details

你可以替换调用方法

tasks.Add(Task.Factory.StartNew(async () => await IncCountWithDictLock("10")))

tasks.Add(Task.Run(async () => await IncCountWithDictLock("10")));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 2012-03-23
    • 1970-01-01
    相关资源
    最近更新 更多