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.
83 lines
2.1 KiB
83 lines
2.1 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 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();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|