You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							92 lines
						
					
					
						
							2.4 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							92 lines
						
					
					
						
							2.4 KiB
						
					
					
				
								using System;
							 | 
						|
								using System.Collections.Generic;
							 | 
						|
								using static System.Collections.Specialized.BitVector32;
							 | 
						|
								
							 | 
						|
								namespace Apewer.Internals
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								    /// <summary>整数锁。</summary>
							 | 
						|
								    internal sealed class Int32Locker : Locker<int>
							 | 
						|
								    {
							 | 
						|
								
							 | 
						|
								        /// <summary>获取整数的哈希值。</summary>
							 | 
						|
								        protected override int GetHash(int target) => target;
							 | 
						|
								
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /// <summary>整数锁。</summary>
							 | 
						|
								    internal sealed class Int64Locker : Locker<long>
							 | 
						|
								    {
							 | 
						|
								
							 | 
						|
								        /// <summary>获取整数的哈希值。</summary>
							 | 
						|
								        protected override int GetHash(long target) => target.GetHashCode();
							 | 
						|
								
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /// <summary>文本锁。</summary>
							 | 
						|
								    internal sealed class TextLocker : Locker<string>
							 | 
						|
								    {
							 | 
						|
								
							 | 
						|
								        /// <summary>获取文本的哈希值。</summary>
							 | 
						|
								        protected override int GetHash(string target) => target == null ? 0 : target.GetHashCode();
							 | 
						|
								
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /// <summary>锁。</summary>
							 | 
						|
								    internal abstract class Locker<TTarget>
							 | 
						|
								    {
							 | 
						|
								
							 | 
						|
								        Dictionary<int, Class<object>> _pool = new Dictionary<int, Class<object>>();
							 | 
						|
								
							 | 
						|
								        /// <summary>获取目标的哈希值。</summary>
							 | 
						|
								        protected abstract int GetHash(TTarget key);
							 | 
						|
								
							 | 
						|
								        /// <summary>清除所有缓存的锁。</summary>
							 | 
						|
								        public void Clear()
							 | 
						|
								        {
							 | 
						|
								            lock (_pool)
							 | 
						|
								            {
							 | 
						|
								                _pool.Clear();
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        Class<object> GetLocker(TTarget target)
							 | 
						|
								        {
							 | 
						|
								            var key = GetHash(target);
							 | 
						|
								            lock (_pool)
							 | 
						|
								            {
							 | 
						|
								                if (_pool.TryGetValue(key, out var locker))
							 | 
						|
								                {
							 | 
						|
								                    return locker;
							 | 
						|
								                }
							 | 
						|
								                else
							 | 
						|
								                {
							 | 
						|
								                    locker = new Class<object>(new object());
							 | 
						|
								                    _pool.Add(key, locker);
							 | 
						|
								                    return locker;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>锁定目标,执行 Action。</summary>
							 | 
						|
								        public void InLock(TTarget target, Action action)
							 | 
						|
								        {
							 | 
						|
								            if (action == null) return;
							 | 
						|
								
							 | 
						|
								            var locker = GetLocker(target);
							 | 
						|
								            lock (locker.Value) action.Invoke();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /// <summary>锁定目标,执行 Func。</summary>
							 | 
						|
								        public TResult InLock<TResult>(TTarget target, Func<TResult> func)
							 | 
						|
								        {
							 | 
						|
								            if (func == null) return default;
							 | 
						|
								
							 | 
						|
								            var locker = GetLocker(target);
							 | 
						|
								            lock (locker.Value) return func.Invoke();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								}
							 | 
						|
								
							 |