public void ForEach(Action <DateTime> action) { if (action is null) { throw new ArgumentNullException(nameof(action)); } ReaderWriterLockHelper.Read((ref List <DateTime> dateTimes) => { dateTimes.ForEach(action); }); }
public bool Execute <T> (string text, bool ignoreCase, out T returnValue, Sender sender = default, int permissionLevel = default) { if (!Parse(new StringReader(text), out string name, out List <LexicalAnalyzerToken <TextCommandTokenType> > parameters)) { returnValue = default; return(false); } TextCommandInput <Sender> input = new TextCommandInput <Sender> (text, sender, permissionLevel, ignoreCase); T innerReturnValue = default; bool executed = false; ReaderWriterLockHelper.Read(commands => { foreach (var command in commands) { if (parameters.Count < command.Parameters.Length) { continue; } if (!command.IsParams && parameters.Count > command.Parameters.Length) { continue; } StringComparison stringComparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; if (!command.Names.Exists(commandName => string.Equals(name, commandName, stringComparison))) { continue; } if (MatchParameterType && !MatchParameters(parameters, command.Parameters)) { continue; } object[] values = new object[command.Parameters.Length + TextCommandAPI.RetentionParameterNumber]; try { int index = -TextCommandAPI.RetentionParameterNumber; for (int i = 0; i < values.Length; i++, index++) { if (i < TextCommandAPI.RetentionParameterNumber) { switch (i) { case 0: values[i] = sender; break; default: throw new NotImplementedException(i.ToString()); } continue; } if (i == values.Length - 1 && command.IsParams) { Array array = Array.CreateInstance(command.Parameters[index].ElementType, parameters.Count - command.Parameters.Length + 1); for (int n = 0; n < array.Length; n++) { array.SetValue(Convert.ChangeType(parameters[index + n].Value, command.Parameters[index].ElementType), n); } values[i] = array; continue; } values[i] = Convert.ChangeType(parameters[index].Value, command.Parameters[index].ParameterInfo.ParameterType); } } catch { continue; } if (EnablePermission) { bool skip = false; OnCheckingPermission?.Invoke(command, input, ref skip); if (!skip) { if (permissionLevel.CompareTo(command.PermissionLevel) < 0) { OnCheckedPermission?.Invoke(command, input, false); continue; } OnCheckedPermission?.Invoke(command, input, true); } } bool cancel = false; OnExecuting?.Invoke(command, input, ref cancel); if (cancel) { return; } innerReturnValue = (T)command.MethodInfo.Invoke(command.Instance, values); executed = true; OnExecuted?.Invoke(command, input, innerReturnValue); return; } }); returnValue = innerReturnValue; return(executed); }
public void TestMethod1() { ReaderWriterLockHelper readerWriterLock = new ReaderWriterLockHelper(); AutoResetEvent autoResetEvent = new AutoResetEvent(false); int threadNumber = 3; int value = 10000; new Thread(() => { while (true) { bool needBreak = false; readerWriterLock.Read(() => { if (value <= 0) { needBreak = true; return; } Console.WriteLine($"线程 {Thread.CurrentThread.Name} 计数 {value}"); }); if (needBreak) { break; } } threadNumber--; if (threadNumber <= 0) { autoResetEvent.Set(); } }) { Name = "读" }.Start(); new Thread(() => { while (true) { bool needBreak = false; readerWriterLock.Write(() => { if (value <= 0) { needBreak = true; return; } value--; Console.WriteLine($"线程 {Thread.CurrentThread.Name} 计数 {value}"); }); if (needBreak) { break; } } threadNumber--; if (threadNumber <= 0) { autoResetEvent.Set(); } }) { Name = "写" }.Start(); new Thread(() => { while (true) { if (!readerWriterLock.TryEnterReadLock()) { continue; } try { if (!readerWriterLock.TryEnterWriteLock(out ReaderWriterLockCookie cookie)) { continue; } try { if (value <= 0) { break; } value--; Console.WriteLine($"线程 {Thread.CurrentThread.Name} 计数 {value}"); } finally { readerWriterLock.ExitWriteLock(ref cookie); } } finally { readerWriterLock.ExitReadLock(); } } threadNumber--; if (threadNumber <= 0) { autoResetEvent.Set(); } }) { Name = "读写" }.Start();