|
|
@ -1,18 +1,36 @@ |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Text; |
|
|
|
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 TextLocker : Locker<string> |
|
|
|
{ |
|
|
|
|
|
|
|
/// <summary>获取文本的哈希值。</summary>
|
|
|
|
protected override int GetHash(string target) => target == null ? 0 : target.GetHashCode(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>锁。</summary>
|
|
|
|
internal class Locker |
|
|
|
internal abstract class Locker<TTarget> |
|
|
|
{ |
|
|
|
|
|
|
|
Dictionary<int, Class<object>> _pool = new Dictionary<int, Class<object>>(); |
|
|
|
|
|
|
|
/// <summary>标记指定的字符串。</summary>
|
|
|
|
static int Key(string s) => s == null ? 0 : s.GetHashCode(); |
|
|
|
/// <summary>获取目标的哈希值。</summary>
|
|
|
|
protected abstract int GetHash(TTarget key); |
|
|
|
|
|
|
|
/// <summary>清除所有缓存的锁。</summary>
|
|
|
|
public void Clear() |
|
|
@ -23,50 +41,40 @@ namespace Apewer.Internals |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>锁定字符串,执行 Action。</summary>
|
|
|
|
public void InLock(string text, Action action) |
|
|
|
Class<object> GetLocker(TTarget target) |
|
|
|
{ |
|
|
|
if (action == null) return; |
|
|
|
|
|
|
|
var key = Key(text); |
|
|
|
Class<object> locker; |
|
|
|
var key = GetHash(target); |
|
|
|
lock (_pool) |
|
|
|
{ |
|
|
|
if (!_pool.TryGetValue(key, out locker)) |
|
|
|
if (_pool.TryGetValue(key, out var locker)) |
|
|
|
{ |
|
|
|
locker = new Class<object>(); |
|
|
|
return locker; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
locker = new Class<object>(new object()); |
|
|
|
_pool.Add(key, locker); |
|
|
|
return locker; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
lock (locker.Value) |
|
|
|
{ |
|
|
|
action.Invoke(); |
|
|
|
} |
|
|
|
/// <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 T InLock<T>(string text, Func<T> func) |
|
|
|
/// <summary>锁定目标,执行 Func。</summary>
|
|
|
|
public TResult InLock<TResult>(TTarget target, Func<TResult> func) |
|
|
|
{ |
|
|
|
if (func == null) return default; |
|
|
|
|
|
|
|
var key = Key(text); |
|
|
|
Class<object> locker; |
|
|
|
lock (_pool) |
|
|
|
{ |
|
|
|
if (!_pool.TryGetValue(key, out locker)) |
|
|
|
{ |
|
|
|
locker = new Class<object>(); |
|
|
|
_pool.Add(key, locker); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
T result; |
|
|
|
lock (locker.Value) |
|
|
|
{ |
|
|
|
result = func.Invoke(); |
|
|
|
} |
|
|
|
return result; |
|
|
|
var locker = GetLocker(target); |
|
|
|
lock (locker.Value) return func.Invoke(); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|