Ejemplo n.º 1
0
        public User GetUserFromId(int id)
        {
            try
            {
                this.readerWriterLock.EnterReadLock();

                if (this.userCache.ContainsKey(id))
                {
                    return(this.userCache[id]);
                }
            }
            finally
            {
                this.readerWriterLock.ExitReadLock();
            }

            // We don't use a global lock while reading the user from the table
            // We lock only the 'id' that we are trying to retrieve. For each id,
            // we use a dummy lock object. This lock object is used to synchronize
            // the threads attempting to read the same user object.
            // The list of lock objects are stored in a dictionary.
            // We first lock the dictionary and get/create a lock object for this id.
            // Then we lock the lock object and check if another thread added the user to
            // the cache already. If so, we return.
            // Else we read it from the database, add the user to the user cache and exit.
            object lockObject = null;

            try
            {
                lock (this.userLockObjects)
                {
                    if (!this.userLockObjects.ContainsKey(id))
                    {
                        this.userLockObjects.Add(id, new object());
                    }

                    lockObject = this.userLockObjects[id];
                }

                Monitor.Enter(lockObject);

                if (this.userCache.ContainsKey(id))
                {
                    return(this.userCache[id]);
                }

                User user = UserDbQuery.InternalGetUserFromId(id);

                if (user == null)
                {
                    return(null);
                }

                this.userCache.Add(id, user);
                if (user.UserData.UserType != UserType.Group)
                {
                    this.phoneUserCache.Add(user.UserData.PhoneNumber, user);
                }

                return(user);
            }
            finally
            {
                Monitor.Exit(lockObject);

                lock (this.userLockObjects)
                {
                    if (this.userLockObjects.ContainsKey(id))
                    {
                        this.userLockObjects.Remove(id);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public List <User> GetUsersFromPhones(List <string> phoneNumbers)
        {
            List <User>            users = new List <User>();
            List <string>          notFoundPhoneNumbers = new List <string>();
            Dictionary <int, User> addedUsers           = new Dictionary <int, User>();

            foreach (string phoneNumber in phoneNumbers)
            {
                try
                {
                    this.readerWriterLock.EnterReadLock();

                    if (this.phoneUserCache.ContainsKey(phoneNumber))
                    {
                        User user = this.phoneUserCache[phoneNumber];
                        if (!addedUsers.ContainsKey(user.UserData.Id))
                        {
                            users.Add(this.phoneUserCache[phoneNumber]);
                            addedUsers.Add(user.UserData.Id, user);
                        }
                    }
                    else
                    {
                        notFoundPhoneNumbers.Add(phoneNumber);
                    }
                }
                finally
                {
                    this.readerWriterLock.ExitReadLock();
                }
            }

            List <User> notFoundUsers = UserDbQuery.InternalGetUsersFromPhones(notFoundPhoneNumbers);

            foreach (User u in notFoundUsers)
            {
                if (!addedUsers.ContainsKey(u.UserData.Id))
                {
                    users.Add(u);
                    addedUsers.Add(u.UserData.Id, u);
                }
            }

            foreach (User user in notFoundUsers)
            {
                object lockObject = null;

                try
                {
                    lock (this.userLockObjects)
                    {
                        if (!this.userLockObjects.ContainsKey(user.UserData.Id))
                        {
                            this.userLockObjects.Add(user.UserData.Id, new object());
                        }

                        lockObject = this.userLockObjects[user.UserData.Id];
                    }

                    Monitor.Enter(lockObject);

                    if (this.userCache.ContainsKey(user.UserData.Id))
                    {
                        continue;
                    }

                    this.userCache.Add(user.UserData.Id, user);
                    this.phoneUserCache.Add(user.UserData.PhoneNumber, user);
                }
                finally
                {
                    Monitor.Exit(lockObject);

                    lock (this.userLockObjects)
                    {
                        if (this.userLockObjects.ContainsKey(user.UserData.Id))
                        {
                            this.userLockObjects.Remove(user.UserData.Id);
                        }
                    }
                }
            }

            return(users);
        }