我有这段代码,如果该任务是为相同的输入创建的,我想等待正在进行的任务。这是我正在做的事情的最小再现。
private static ConcurrentDictionary<int, Task<int>> _tasks = new ConcurrentDictionary<int, Task<int>>();
private readonly ExternalService _service;
public async Task SampleTask(){
var result = await _service.DoSomething();
await Task.Delay(1000) //this task takes some time do finish
return result;
}
public async Task<int> DoTask(int key) {
var task = _tasks.GetOrAdd(key, _ => SampleTask());
var taskResult = await task;
_tasks.TryRemove(key, out task);
return taskResult;
}
Run Code Online (Sandbox Code Playgroud)
我正在编写一个测试,以确保当多个请求想要(大致)同时执行任务时等待相同的任务。我通过模拟并计算被调用的_service次数来做到这一点。_service.DoSomething()如果对 where 的调用DoTask(int key)大致在同一时间进行,则应该只进行一次。
然而,结果表明,如果我DoTask(int key)多次调用且调用之间的延迟小于 1~2 毫秒,则两个任务都将创建并执行其实例,SampleTask()其中第二个任务将替换字典中的第一个任务。
考虑到这一点,我们可以说这个方法是真正的线程安全的吗?或者我的问题本身不是线程安全的情况吗?