0

I assume the same logic from this question also applies to the following code snippet? Which would mean that the enumerator will never be a snapshot in time and thus an additional synchronization primitive would be needed. This of course doesn't apply if I interact with the dictionary directly.

public class InMemoryUserStore<TUser> :
        IQueryableUserStore<TUser>
        where TUser : User
    {
        private readonly ConcurrentDictionary<string, TUser> _users = new ConcurrentDictionary<string, TUser>();

        #region IQueryableUserStore<TUser>

        /// <summary>
        /// Return the dictionary as a <see cref="IQueryable{TUser}"/>.
        /// </summary>
        public IQueryable<TUser> Users => _users.Values.AsQueryable();

        #region CRUD

        /// <summary>
        /// Find a user by id.
        /// </summary>
        public Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken))
        {
            var user = Users.FirstOrDefault(u => u.Id == userId);
            if (user != null)
            {
                return Task.FromResult(user);
            }

            return Task.FromResult<TUser>(null);
        }
}
HansMusterWhatElse
  • 671
  • 1
  • 13
  • 34
  • 2
    As some answers on that question point out, `Values` does return a snapshot, so anything you do with *that* after that point is isolated from the `ConcurrentDictionary` and modifications to it. – Damien_The_Unbeliever Aug 20 '18 at 08:26
  • I do interpret it that as soon as retrieve an enumerator (e.g via LINQ) that I don't get a moment in time. That' why I now added an additional locking mechanism around every LINQ query and any method which modifies the dictionary directly. But you are right, thread safety should be provided by the implementation I've added above. – HansMusterWhatElse Aug 20 '18 at 08:45
  • 1
    No. What `Values` returns is a plain old `List` that has no idea who constructed it or why. Anything you call on that `List` has no way of linking it back, in any way, to the fact that the items in the list were originally contained in a `ConcurrentDictionary`. But if you're going down this route of adding locks, ditch `ConcurrentDictionary` and look at your other options. E.g. an `ImmutableDictionary` can sometimes make an interesting alternative. – Damien_The_Unbeliever Aug 20 '18 at 08:48

0 Answers0