小编Luí*_*ade的帖子

ConcurrentDictionary.GetOrAdd 真的是线程安全的吗?

我有这段代码,如果该任务是为相同的输入创建的,我想等待正在进行的任务。这是我正在做的事情的最小再现。

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()其中第二个任务将替换字典中的第一个任务。

考虑到这一点,我们可以说这个方法是真正的线程安全的吗?或者我的问题本身不是线程安全的情况吗?

c# task

3
推荐指数
1
解决办法
3219
查看次数

标签 统计

c# ×1

task ×1