Browse Source

修正文本锁 Null 引用异常。

master
王厅 1 week ago
parent
commit
c845e3b35d
  1. 76
      Apewer/Internals/Locker.cs
  2. 2
      Apewer/TextUtility.cs

76
Apewer/Internals/Locker.cs

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

2
Apewer/TextUtility.cs

@ -1065,7 +1065,7 @@ namespace Apewer
#region Lock #region Lock
static Locker _locker = new Locker(); static TextLocker _locker = new TextLocker();
/// <summary>锁定文本,在锁中执行函数。</summary> /// <summary>锁定文本,在锁中执行函数。</summary>
/// <param name="text">要锁定的文本。</param> /// <param name="text">要锁定的文本。</param>

Loading…
Cancel
Save