TryGet
will block until any locks are cleared. It is typically a very short block (it does not take long to add or remove a key). It will then return true if the key/value is present and false otherwise. It will not wait for the key to be added.
If you expect the key to be populated by another thread, and you're not sure if it's finished, you could use a while loop. But I've never had to do that. I think if you find yourself writing a while loop in this circumstance you may have a suboptimal design. Consider using GetOrAdd to retrieve the value, which allows you to supply a function to populate the key if it is not present, e.g.
var user = dictionary.GetOrAdd("User", (key) => GetUser());
If you don't want to use GetOrAdd
and you absolutely have to wait for that other thread to finish, try to refactor your code so you have a reference to its SynchronizationContext or its Task. Then a/wait it. That will yield execution in a more efficient manner than a while loop.