title: Is ConcurrentDictionary.GetOrAdd truly thread-safe?
body: <p>I have this piece of code where I want to await on a ongoing task if that task was created for the same input. Here is minimal reproduction of what I'm doing.</p>
  
  <pre class="lang-cs prettyprint-override"><code>private static ConcurrentDictionary&lt;int, Task&lt;int&gt;&gt; _tasks = new ConcurrentDictionary&lt;int, Task&lt;int&gt;&gt;();
  
  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&lt;int&gt; DoTask(int key) {
     var task = _tasks.GetOrAdd(key, _ =&gt; SampleTask());
     var taskResult = await task;
     _tasks.TryRemove(key, out task);
     return taskResult;
  }
  </code></pre>
  
  <p>I'm writing a test to ensure the same task is awaited when multiple requests want to perform the task at (roughly) the same time. I'm doing that by mocking <code>_service</code> and counting how many times <code>_service.DoSomething()</code> is being called. It should be only once if the calls to <code>DoTask(int key)</code> where made at roughly the same time.</p>
  
  <p>However, the results show me that if I call <code>DoTask(int key)</code> more than once with a delay between calls of less than 1~2ms, both tasks will create and execute its on instance of <code>SampleTask()</code> with the second one replacing the first one in the dictionary.</p>
  
  <p>Considering this, can we say that this method is truly thread-safe? Or isn't my problem a case of thread-safety per se?</p>