How to lock on an integer in C#?

后端 未结 14 2246
醉梦人生
醉梦人生 2020-12-05 14:44

Is there any way to lock on an integer in C#? Integers can not be used with lock because they are boxed (and lock only locks on references).

The scenario is as follo

14条回答
  •  悲&欢浪女
    2020-12-05 15:08

    I've read a lot of comments mentioning that locking isn't safe for web applications, but, other than web farms, I haven't seen any explanations of why. I would be interested in hearing the arguments against it.

    I have a similar need, though I'm caching re-sized images on the hard drive (which is obviously a local action so a web farm scenario isn't an issue).

    Here is a redone version of what @Configurator posted. It includes a couple features that @Configurator didn't include:

    1. Unlocking: Ensures the list doesn't grow unreasonably large (we have millions of photos and we can have many different sizes for each).
    2. Generic: Allows locking based on different data types (such as int or string).

    Here's the code...

    /// 
    /// Provides a way to lock a resource based on a value (such as an ID or path).
    /// 
    public class Synchronizer
    {
    
        private Dictionary mLocks = new Dictionary();
        private object mLock = new object();
    
        /// 
        /// Returns an object that can be used in a lock statement. Ex: lock(MySync.Lock(MyValue)) { ... }
        /// 
        /// 
        /// 
        public SyncLock Lock(T value)
        {
            lock (mLock)
            {
                SyncLock theLock;
                if (mLocks.TryGetValue(value, out theLock))
                    return theLock;
    
                theLock = new SyncLock(value, this);
                mLocks.Add(value, theLock);
                return theLock;
            }
        }
    
        /// 
        /// Unlocks the object. Called from Lock.Dispose.
        /// 
        /// 
        public void Unlock(SyncLock theLock)
        {
            mLocks.Remove(theLock.Value);
        }
    
        /// 
        /// Represents a lock for the Synchronizer class.
        /// 
        public class SyncLock
            : IDisposable
        {
    
            /// 
            /// This class should only be instantiated from the Synchronizer class.
            /// 
            /// 
            /// 
            internal SyncLock(T value, Synchronizer sync)
            {
                Value = value;
                Sync = sync;
            }
    
            /// 
            /// Makes sure the lock is removed.
            /// 
            public void Dispose()
            {
                Sync.Unlock(this);
            }
    
            /// 
            /// Gets the value that this lock is based on.
            /// 
            public T Value { get; private set; }
    
            /// 
            /// Gets the synchronizer this lock was created from.
            /// 
            private Synchronizer Sync { get; set; }
    
        }
    
    }
    

    Here's how you can use it...

    public static readonly Synchronizer sPostSync = new Synchronizer();
    ....
    using(var theLock = sPostSync.Lock(myID))
    lock (theLock)
    {
        ...
    }
    

提交回复
热议问题