What is wrong with this solution to locking and managing locked exceptions?

前端 未结 4 392
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-01 02:08

My objective is a convention for thread-safe functionality and exception handling within my application. I\'m relatively new to the concept of thread management/multithread

4条回答
  •  心在旅途
    2021-01-01 02:45

    1. Move the IsCorrupt test and the Monitor.Enter inside the Try
    2. Move the corruption set handling out of finally and into the Catch block (this should only execute if an exception has been thrown)
    3. Don't release the primary lock until after the corruption flag has been set (leave it in the finaly block)
    4. Don't restrict the execption to the calling thread; either rethow it or add it to the coruption dictionary by replacing the bool with the custom execption, and return it with the IsCorrupt Check
    5. For Uncorrupt simply remove the item
    6. There are some issues with the locking sequencing (see below)

    That should cover all the bases

      public static class Locking
    {
        private static readonly Dictionary CorruptionStateDictionary = new Dictionary();
        private static readonly object CorruptionLock = new object();
        public static bool TryLockedAction(object lockObject, Action action, out Exception exception)
        {
            var lockTaken = false;
            exception = null;
            try
            {
                Monitor.Enter(lockObject, ref lockTaken);
    
                if (IsCorrupt(lockObject))
                {
                    exception = new LockingException("Cannot execute locked action on a corrupt object.");
                    return false;
                }
    
                action.Invoke();
            }
            catch (Exception ex)
            {
                var corruptionLockTaken = false;
                exception = ex;
                try
                {
                    Monitor.Enter(CorruptionLock, ref corruptionLockTaken);
    
                    if (CorruptionStateDictionary.ContainsKey(lockObject))
                    {
                        CorruptionStateDictionary[lockObject] = ex;
                    }
                    else
                    {
                        CorruptionStateDictionary.Add(lockObject, ex);
                    }
                }
    
                finally
                {
                    if (corruptionLockTaken)
                    {
                        Monitor.Exit(CorruptionLock);
                    }
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(lockObject);
                }
            }
            return exception == null;
        }
        public static void Uncorrupt(object corruptLockObject)
        {
            var lockTaken = false;
            try
            {
                Monitor.Enter(CorruptionLock, ref lockTaken);
                if (IsCorrupt(corruptLockObject))
                {
                    { CorruptionStateDictionary.Remove(corruptLockObject); }
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(CorruptionLock);
                }
            }
    
        }
        public static bool IsCorrupt(object lockObject)
        {
            Exception ex = null;
            return IsCorrupt(lockObject, out ex);
        }
        public static bool IsCorrupt(object lockObject, out Exception ex)
        {
            var lockTaken = false;
            ex = null;
            try
            {
                Monitor.Enter(CorruptionLock, ref lockTaken);
                if (CorruptionStateDictionary.ContainsKey(lockObject))
                {
                    ex = CorruptionStateDictionary[lockObject];
                }
                return CorruptionStateDictionary.ContainsKey(lockObject);
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(CorruptionLock);
                }
            }           
        }
    }
    

提交回复
热议问题