C#中SemaphoreSlim初始计数设为1时WaitAsync未按预期运行问题求解
问题原因
你遇到的执行结果和预期不符的核心原因是实际运行的代码和你贴出的代码存在差异,结合你的输出结果反推,有两个最可能的错误点:
- 你实际初始化
SemaphoreSlim时传入的初始计数是0而非你写的1:初始计数代表信号量默认可用的许可数,若设为0,调用WaitAsync()时就会进入等待,直到有Release()调用将许可数加1才能继续执行,完全符合你给出的输出结果。 - 你实际在
Task.Run的委托中对Task.Delay(2000)加了await关键字:你贴出的代码中Task.Delay(2000)没有await,这行代码不会产生阻塞,委托会立刻执行输出和Release逻辑,不会等待2秒,和你输出存在2秒间隔的现象不符。
如果你贴出的代码是完全准确的,还有极低概率是测试框架的线程调度优先级问题导致,但这种情况不会出现2秒的等待间隔,进一步说明你实际运行的代码和贴出的存在出入。
解决方法
- 如果你想要
WaitAsync()直接获取许可无需等待,确认SemaphoreSlim的初始化代码为SemaphoreSlim slim = new SemaphoreSlim(1);即可,此时正常执行顺序会符合你的预期:Waiting Done Unleash! - 如果你需要
Task.Delay(2000)真正生效等待2秒,将Task.Run的委托修改为异步lambda即可,不会影响信号量的获取逻辑:_ = Task.Run(async () => { await Task.Delay(2000); _testOutputHelper.WriteLine("Unleash!"); slim.Release(); }); - 如果你当前的输出结果就是你想要的效果(等后台任务执行完再执行主线程后续逻辑),直接将
SemaphoreSlim的初始计数改为0即可,符合当前的执行逻辑。
内容的提问来源于stack exchange,提问作者user1034912
相关产品推荐
相关产品推荐

