diff --git a/Apewer/Internals/Locker.cs b/Apewer/Internals/Locker.cs new file mode 100644 index 0000000..c38bdc5 --- /dev/null +++ b/Apewer/Internals/Locker.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Apewer.Internals +{ + + /// 锁。 + internal class Locker + { + + Dictionary> _pool = new Dictionary>(); + + /// 标记指定的字符串。 + static int Key(string s) => s == null ? 0 : s.GetHashCode(); + + /// 清除所有缓存的锁。 + public void Clear() + { + lock (_pool) + { + _pool.Clear(); + } + } + + /// 锁定字符串,执行 Action。 + public void InLock(string text, Action action) + { + if (action == null) return; + + var key = Key(text); + Class locker; + lock (_pool) + { + if (!_pool.TryGetValue(key, out locker)) + { + locker = new Class(); + _pool.Add(key, locker); + } + } + + lock (locker.Value) + { + action.Invoke(); + } + } + + /// 锁定字符串,执行 Func。 + public T InLock(string text, Func func) + { + if (func == null) return default; + + var key = Key(text); + Class locker; + lock (_pool) + { + if (!_pool.TryGetValue(key, out locker)) + { + locker = new Class(); + _pool.Add(key, locker); + } + } + + T result; + lock (locker.Value) + { + result = func.Invoke(); + } + return result; + } + + } + + +} diff --git a/Apewer/TextUtility.cs b/Apewer/TextUtility.cs index 00cb80a..e0d964a 100644 --- a/Apewer/TextUtility.cs +++ b/Apewer/TextUtility.cs @@ -1044,6 +1044,32 @@ namespace Apewer return trim ? Trim(middle, trimBlank) : middle; } + #region Lock + + static Locker _locker = new Locker(); + + /// 锁定文本,在锁中执行函数。 + /// 要锁定的文本。 + /// 要在锁中执行的函数。 + /// + public static T Lock(this string text, Func inLock) + { + if (inLock == null) throw new ArgumentNullException(nameof(inLock)); + return _locker.InLock(text, inLock); + } + + /// 锁定文本,在锁中执行函数。 + /// 要锁定的文本。 + /// 要在锁中执行的函数。 + /// + public static void Lock(this string text, Action inLock) + { + if (inLock == null) throw new ArgumentNullException(nameof(inLock)); + _locker.InLock(text, inLock); + } + + #endregion + #region encoding /// 检查字节数组包含 UTF-8 BOM 头。