public bool EnQueue(T item) { locker.EnterWriteLock(); var isSuccess = false; if (keyList.Add(item)) { var indexStart = _rear; _rear = (indexStart + 1) % _capacity; if (_rear == _front) { _front = (++_front) % _capacity; } valueList[indexStart] = item; UpdateCount(1); isSuccess = true; } locker.ExitWriteLock(); return(isSuccess); }
/// <summary> /// /// </summary> /// <param name="entity"></param> /// <returns>True if the entity was added to the scene graph, false if /// it was updated</returns> public bool AddOrUpdate(ISceneEntity entity) { bool added; m_syncRoot.EnterWriteLock(); try { if (!m_entityLocalIDs.ContainsKey(entity.LocalID)) { // Sanity check if (m_entityUUIDs.ContainsKey(entity.ID)) { throw new ArgumentException("Cannot add entity with LocalID " + entity.LocalID + ", ID " + entity.ID + " already exists in the scene"); } // Insert this entity into the scene graph, uint map, and UUID map m_entityLocalIDs.Add(entity.LocalID, entity); m_entityUUIDs.Add(entity.ID, entity); added = true; } else { added = false; } // If this is a scene presence, add/update it in the presence collection if (entity is IScenePresence) { m_presences.Add(entity.ID, (IScenePresence)entity); } } finally { m_syncRoot.ExitWriteLock(); } return(added); }
private bool AddOrUpdate(string filename, byte[] data) { m_rwLock.EnterWriteLock(); try { if (File.Exists(filename)) { // Already exists File.WriteAllBytes(filename, data); return(false); } else { // New entry CreateDirectories(filename); File.WriteAllBytes(filename, data); return(true); } } catch (Exception ex) { m_log.Error("Failed to store local data to " + filename + ": " + ex.Message); } finally { m_rwLock.ExitWriteLock(); } return(false); }
private HttpStatusCode CancelCrossing(CrossingRequest cross) { m_crossLock.EnterUpgradeableReadLock(); try { if (m_crossings.ContainsKey(cross.uuid)) { m_crossLock.EnterWriteLock(); try { m_crossings.Remove(cross.uuid); return(HttpStatusCode.OK); } finally { m_crossLock.ExitWriteLock(); } } else { return(HttpStatusCode.NotFound); } } finally { m_crossLock.ExitUpgradeableReadLock(); } }
public new void Clear() { SyncRoot.EnterWriteLock(); nameCache.Clear(); nameUUIDHandleCache.Clear(); base.Clear(); SyncRoot.ExitWriteLock(); }
public bool AddOrUpdate(GridRegion rinfo, int expire) { //if (rinfo == null || disposed) if (rinfo == null) { return(false); } bool gotLock = false; try { try { } finally { m_rwLock.EnterWriteLock(); gotLock = true; } int newexpire = (int)(Util.GetTimeStamp() - starttimeS) + expire; ulong handle = rinfo.RegionHandle & HANDLEMASK; if (m_expireControl.ContainsKey(handle)) { if (m_expireControl[handle] < newexpire) { m_expireControl[handle] = newexpire; } } else { m_expireControl[handle] = newexpire; } if (m_innerHandles.TryGetValue(handle, out GridRegion oldr)) { removeFromInner(oldr); } addToInner(rinfo); m_byHandler[handle] = rinfo; m_byName[rinfo.RegionName.ToLowerInvariant()] = rinfo; m_byUUID[rinfo.RegionID] = rinfo; return(true); } finally { if (gotLock) { m_rwLock.ExitWriteLock(); } } }
internal PacketReceiver(string LocalAddress) : base (LocalAddress) { packetReceiver = new Queue(); tokenSource = new CancellationTokenSource(); readerWriterLock = new ReaderWriterLockSlim(); tokenSource.Token.Register(() => { // Clear on cancel packetReceiver.Clear(); }); var thReceiveQueue = Task.Factory.StartNew(() => { while (tokenSource.Token.IsCancellationRequested == false) { readerWriterLock.EnterUpgradeableReadLock(); if (packetReceiver.Count > 0) { readerWriterLock.EnterWriteLock(); byte[] data = (byte[])packetReceiver.Dequeue(); readerWriterLock.ExitWriteLock(); if (OnNewPacketReceived != null) OnNewPacketReceived(this, new NewPacketEventArgs(data)); } readerWriterLock.ExitUpgradeableReadLock(); } }); }
public static void runAsyncProc(log_parsed_data data, List <type_count_data> logTypesCnt) { // 시간 오래 걸린다. data.logDetail = runExternalProgram(external_progName, data.logDetail).Replace("\r\n", string.Empty); // 타입 별 output 쓰기 (append모드) System.IO.StreamWriter wfile_type = null; foreach (type_count_data t in logTypesCnt) { if (data.logType == t.logType) { wfile_type = t.wfile_output;//new System.IO.StreamWriter(String.Format(outputTypeLg, "1", t.logType), false); } } //wfile_type = new System.IO.StreamWriter(String.Format(outputTypeLg, "1", data.logType), true); _readWriteLock.EnterWriteLock(); { if (wfile_type != null) { wfile_type.WriteLine(data.logTime + "#" + data.logType + data.logDetail); //Debug.WriteLine(data.logTime + "#" + data.logType + "#" + data.logDetail); } //wfile.WriteLineAsync wfile_type.Flush(); } _readWriteLock.ExitWriteLock(); }
public TValue this[TKey key] { get { _lock.EnterReadLock(); try { if (!_dictionary.TryGetValue(key, out var value)) { throw new InvalidOperationException($"key {key} doesn't exist"); } return(value); } finally { _lock.ExitReadLock(); } } set { _lock.EnterWriteLock(); _dictionary[key] = value; _lock.ExitWriteLock(); } }
/// <summary> /// 写入以小时分割的日志文件 /// </summary> /// <param name="Msg">要记录的消息</param> /// <param name="li">日志信息类</param> /// <param name="LogPath">日志所在文件夹</param> /// <returns></returns> internal static string WriteLineToTimeFile(string Msg, LogInfo li, string LogPath) { if (string.IsNullOrEmpty(Msg)) { return("输入参数Msg为null或者值为空不符合记录要求!"); } StreamWriter sw = null; try { Slim.EnterWriteLock(); //string Dir = System.Windows.Forms.Application.StartupPath + @"\GLogs\" + DateTime.Now.ToString("yyyy年MM月dd日"); checkLog(LogPath); string file = DateTime.Now.ToString("yyyy年MM月dd日HH时") + ".log"; checkfile(LogPath, file); string fileName = LogPath + "\\" + file; sw = File.AppendText(fileName); sw.WriteLine("日志时间:" + DateTime.Now.ToString() + ",文件名:" + li.FileName + ",方法名:" + li.MethodName + "行号:" + li.Line + ",列:" + li.Column + ",日志类型:" + li.LogType); sw.WriteLine("日志内容:" + Msg); return(nameof(WriteLineToTimeFile) + "日志记录操作成功!"); } catch (Exception ex) { return(nameof(WriteLineToTimeFile) + "日志记录发生错误:" + ex.Message); } finally { sw.Close(); Slim.ExitWriteLock(); } }
public static PocoData ForType(Type t) { //#if !PETAPOCO_NO_DYNAMIC // if (t == typeof(System.Dynamic.ExpandoObject)) // throw new InvalidOperationException("Can't use dynamic types with this method"); //#endif // Check cache RWLock.EnterReadLock(); PocoData pd; try { if (m_PocoDatas.TryGetValue(t, out pd)) { return(pd); } } finally { RWLock.ExitReadLock(); } // Cache it RWLock.EnterWriteLock(); try { // Check again if (m_PocoDatas.TryGetValue(t, out pd)) { return(pd); } // Create it pd = new PocoData(t); m_PocoDatas.Add(t, pd); } finally { RWLock.ExitWriteLock(); } return(pd); }
void cleaner_Elapsed(object state) { var timeToClean = DateTime.Now.AddMinutes(-5); try { rwlock.EnterWriteLock(); while (codes.Count > 0 && codes.Peek().UseDate < timeToClean) { codes.Dequeue(); } } finally { rwlock.ExitWriteLock(); } }
public void EntersWriteLock() { var slim = new ReaderWriterLockSlim(); var token = slim.Write(); Assert.IsTrue(slim.IsWriteLockHeld); slim.ExitWriteLock(); slim.Dispose(); }
public static void EnterExit() { using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { Assert.False(rwls.IsReadLockHeld); rwls.EnterReadLock(); Assert.True(rwls.IsReadLockHeld); rwls.ExitReadLock(); Assert.False(rwls.IsReadLockHeld); Assert.False(rwls.IsUpgradeableReadLockHeld); rwls.EnterUpgradeableReadLock(); Assert.True(rwls.IsUpgradeableReadLockHeld); rwls.ExitUpgradeableReadLock(); Assert.False(rwls.IsUpgradeableReadLockHeld); Assert.False(rwls.IsWriteLockHeld); rwls.EnterWriteLock(); Assert.True(rwls.IsWriteLockHeld); rwls.ExitWriteLock(); Assert.False(rwls.IsWriteLockHeld); Assert.False(rwls.IsUpgradeableReadLockHeld); rwls.EnterUpgradeableReadLock(); Assert.False(rwls.IsWriteLockHeld); Assert.True(rwls.IsUpgradeableReadLockHeld); rwls.EnterWriteLock(); Assert.True(rwls.IsWriteLockHeld); rwls.ExitWriteLock(); Assert.False(rwls.IsWriteLockHeld); Assert.True(rwls.IsUpgradeableReadLockHeld); rwls.ExitUpgradeableReadLock(); Assert.False(rwls.IsUpgradeableReadLockHeld); Assert.True(rwls.TryEnterReadLock(0)); rwls.ExitReadLock(); Assert.True(rwls.TryEnterReadLock(Timeout.InfiniteTimeSpan)); rwls.ExitReadLock(); Assert.True(rwls.TryEnterUpgradeableReadLock(0)); rwls.ExitUpgradeableReadLock(); Assert.True(rwls.TryEnterUpgradeableReadLock(Timeout.InfiniteTimeSpan)); rwls.ExitUpgradeableReadLock(); Assert.True(rwls.TryEnterWriteLock(0)); rwls.ExitWriteLock(); Assert.True(rwls.TryEnterWriteLock(Timeout.InfiniteTimeSpan)); rwls.ExitWriteLock(); } }
private static void AtomWrite(ReaderWriterLockSlim readerWriterLockSlim, Action action) { readerWriterLockSlim.EnterWriteLock(); try { action(); } finally { readerWriterLockSlim.ExitWriteLock(); } }
public void Add(TKey1 key1, TKey2 key2, TValue value) { rwLock.EnterWriteLock(); try { if (Dictionary1.ContainsKey(key1)) { if (!Dictionary2.ContainsKey(key2)) { throw new ArgumentException("key1 exists in the dictionary but not key2"); } } else if (Dictionary2.ContainsKey(key2)) { if (!Dictionary1.ContainsKey(key1)) { throw new ArgumentException("key2 exists in the dictionary but not key1"); } } Dictionary1[key1] = value; Dictionary2[key2] = value; } finally { rwLock.ExitWriteLock(); } }
public void n3_multithreading() { int run = 1; int count = 1; const int max = 64; var exceptions = new List<Exception>(); var locker = new ReaderWriterLockSlim(); locker.EnterWriteLock(); for (int i = 0; i < max; i++) { ThreadPool.QueueUserWorkItem((_) => { Interlocked.Increment(ref count); locker.EnterReadLock(); locker.ExitReadLock(); try { while (Thread.VolatileRead(ref run) != 0) { DestroyReaders( CreateReaders(16), 0, false); } } catch (Exception ex) { exceptions.Add(ex); } Interlocked.Increment(ref count); }); } while (Thread.VolatileRead(ref count) < max) Thread.Sleep(100); count = 1; locker.ExitWriteLock(); Thread.Sleep(60000); run = 0; while (Thread.VolatileRead(ref count) < max) Thread.Sleep(1000); if (exceptions.Count > 0) throw exceptions[0]; }
/// <summary> /// Removes the category. /// </summary> /// <param name="category">The category.</param> /// <param name="culture">The culture.</param> /// <returns></returns> public bool RemoveCategory(string category, string culture) { locker.EnterWriteLock(); try { string[] files = Directory.GetFiles(path); foreach (var file in files) { string culture1; string category1; ResXResourceFileHelper.Parse(file, out culture1, out category1); if (category.EqualsOrNullEmpty(category1, StringComparison.CurrentCultureIgnoreCase) && culture1.EqualsOrNullEmpty(culture, StringComparison.CurrentCultureIgnoreCase)) { File.Delete(file); } } return(true); } finally { locker.ExitWriteLock(); } }
public void Move(Site site, string pageFullName, string newParent) { _lock.EnterWriteLock(); try { var page = PageHelper.Parse(site, pageFullName); Page parentPage = null; if (!string.IsNullOrEmpty(newParent)) { parentPage = PageHelper.Parse(site, newParent); if (parentPage == page.Parent || parentPage == page) { throw new KoobooException(string.Format("The page is under '{0}' already".Localize(), newParent)); } } Page newPage = null; if (parentPage != null) { newPage = new Page(parentPage, page.Name); } else { newPage = new Page(site, page.Name); } if (newPage.Exists()) { throw new KoobooException(string.Format("The page '{0}' already exists in '{1}'".Localize(), page.Name, parentPage.FriendlyName)); } Directory.Move(page.PhysicalPath, newPage.PhysicalPath); } finally { _lock.ExitWriteLock(); } }
public TestWindowViewModel() { RWLock = new ReaderWriterLockSlim(); Observable = new ObservableCollection<int>(); BindingOperations.EnableCollectionSynchronization(Observable, RWLock, new CollectionSynchronizationCallback(lockCollection)); AddCommand = new Command(() => { Task.Factory.StartNew(() => { RWLock.EnterWriteLock(); for (int i = 0; i < 10; i++) { Observable.Add(i); } RWLock.ExitWriteLock(); }); }); ClearCommand = new Command(() => { Task.Factory.StartNew(() => { RWLock.EnterWriteLock(); Observable.Move(0,5); RWLock.ExitWriteLock(); int k = 0; for (int i = 0; i < 1000; i++) { k++; } }); }); }
// thread safe한 file write. public void WriteToFile(string text) { _readWriteLock.EnterWriteLock(); using (System.IO.StreamWriter sw = new System.IO.StreamWriter(this.filePath, true)) { if (!customNewLine.Equals(string.Empty)) { sw.NewLine = customNewLine; } //sw.NewLine = "\n"; // 기본은 \r\n 이다. // user defined newline symbol. sw.WriteLine(text); sw.Close(); } _readWriteLock.ExitWriteLock(); }
public override void LogVersion(Page o) { locker.EnterWriteLock(); try { VersionPath versionPath = new VersionPath(o, NextVersionId(o)); IOUtility.EnsureDirectoryExists(versionPath.PhysicalPath); var versionDataFile = Path.Combine(versionPath.PhysicalPath, o.DataFileName); PageProvider provider = new PageProvider(); Kooboo.Runtime.Serialization.DataContractSerializationHelper.Serialize(o, versionDataFile, KnownTypes); } finally { locker.ExitWriteLock(); } }
public void LockVSReaderWriterLockVSReaderWriterLockSlimVSHandle() { TestName("Lock vs. ReaderWriterLock vs. ReaderWriterLockSlim vs. Handle-based"); Object o = new Object(); CodeTimer.Time("Lock perf: Monitor", iterations, () => { Monitor.Enter(o); // Monitor.Exit(o); }); CodeTimer.Time("Lock perf: Lock", iterations, () => { lock (o) { } }); ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(); CodeTimer.Time("Lock perf: ReaderWriterLockSlim", iterations, () => { rwls.EnterWriteLock(); rwls.ExitWriteLock(); }); ReaderWriterLock rwl = new ReaderWriterLock(); CodeTimer.Time("Lock perf: ReaderWriterLock", iterations, () => { rwl.AcquireWriterLock(Timeout.Infinite); rwl.ReleaseWriterLock(); }); Mutex mutex = new Mutex(); CodeTimer.Time("Lock perf: Mutex", iterations, () => { mutex.WaitOne(); mutex.ReleaseMutex(); }); }
/// <summary> /// 仅在 Checkpoint 中调用。 /// 没有拥有任何锁。 /// </summary> public void Cleanup() { ConcurrentDictionary <K, Record <K, V> > tmp = null; snapshotLock.EnterWriteLock(); try { tmp = snapshot; snapshot = new ConcurrentDictionary <K, Record <K, V> >(); } finally { snapshotLock.ExitWriteLock(); } foreach (var e in tmp) { e.Value.Cleanup(); } }
public void Dispose() { ReaderWriterLockSlim copy = Interlocked.Exchange(ref rwlock, null); if (copy == null) { return; } switch (type) { case LockType.Read: copy.ExitReadLock(); break; case LockType.UpgradeableRead: copy.ExitUpgradeableReadLock(); break; case LockType.Write: copy.ExitWriteLock(); break; } }
public void Start() { //ReaderWriterLockSlim locker = new ReaderWriterLockSlim(); //ParameterizedThreadStart reader = o => //{ // var innerlocker = locker; // int number = Convert.ToInt32(o); // for (int i = 0; i < 10; i++) // { // //进入读状态 那么下面的 thread2将会暂停运行 // locker.EnterReadLock(); // Console.WriteLine("Reading " + i); // Thread.Sleep(5000); // //退出读状态 下面的thread2将会继续运行 // locker.ExitReadLock(); // } //}; //ParameterizedThreadStart writer = o => //{ // var innerlocker = locker; // for (int i = 11; i < 200; i++) // { // //进入写状态 上面的线程thread1将会暂停运行 // Thread.Sleep(50);//睡一下 给上面的线程 执行锁定 locker.EnterReadLock(); // locker.EnterWriteLock(); // Console.WriteLine("Writing " + i); // //退出写状态 上面的线程thread1将会继续运行 // Thread.Sleep(500); // locker.ExitWriteLock(); // } //}; //Thread thread1 = new Thread(reader); //thread1.Start(); //Thread thread2 = new Thread(writer); //thread2.Start(); ReaderWriterLockSlim locker = new ReaderWriterLockSlim(); new Thread(new ParameterizedThreadStart(delegate { for (int i = 0; i < 100; i++) { Thread.Sleep(1); locker.EnterWriteLock(); Thread.Sleep(50); list.Add("t1-" + i); locker.ExitWriteLock(); } })).Start(); new Thread(new ParameterizedThreadStart(delegate { for (int i = 0; i < 100; i++) { Thread.Sleep(1); locker.EnterReadLock(); //locker.EnterWriteLock(); Thread.Sleep(50); list.Add("t2-" + i); //locker.ExitWriteLock(); locker.ExitReadLock(); } })).Start(); Thread.Sleep(20000);//20秒后输出结果 foreach (var item in list) { Console.WriteLine(item); } //总结 只要使用了同一个锁 那么 只要锁进入了任何一个状态 例如 EnterWriteLock 那么EnterReadLock 或者另外一个EnterWriteLock 所在的线程将会暂停运行 反之一样 Console.ReadLine(); }
public static void WritersAreMutuallyExclusiveFromWriters() { using (Barrier barrier = new Barrier(2)) using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { Task.WaitAll( Task.Run(() => { rwls.EnterWriteLock(); barrier.SignalAndWait(); Assert.True(rwls.IsWriteLockHeld); barrier.SignalAndWait(); rwls.ExitWriteLock(); }), Task.Run(() => { barrier.SignalAndWait(); Assert.False(rwls.TryEnterWriteLock(0)); Assert.False(rwls.IsReadLockHeld); barrier.SignalAndWait(); })); } }
public void EnterWriteLock_MultiRead () { var v = new ReaderWriterLockSlim (); int local = 10; var r = from i in Enumerable.Range (1, 10) select new Thread (() => { v.EnterReadLock (); Assert.AreEqual (11, local); }); v.EnterWriteLock (); var threads = r.ToList (); foreach (var t in threads) { t.Start (); } Thread.Sleep (200); local = 11; // FIXME: Don't rely on Thread.Sleep (200) Assert.AreEqual (0, v.WaitingWriteCount, "in waiting write"); Assert.AreEqual (10, v.WaitingReadCount, "in waiting read"); Assert.AreEqual (0, v.WaitingUpgradeCount, "in waiting upgrade"); v.ExitWriteLock (); foreach (var t in threads) { // Console.WriteLine (t.ThreadState); t.Join (); } }
public void Refresh() { m_ReadWriterLock.EnterWriteLock(); m_VisibleQueueStatus = VisibleQueueStatus.Refresh; m_ReadWriterLock.ExitWriteLock(); }
public void RecursiveWriteReadAcquisitionInterleaving() { var v = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); v.EnterWriteLock(); Assert.IsTrue(v.IsWriteLockHeld, "#1"); bool result = true; var t = new Thread(delegate () { result = v.TryEnterReadLock(100); }); t.Start(); t.Join(); Assert.IsFalse(result, "#2"); v.ExitWriteLock(); t = new Thread(delegate () { result = v.TryEnterReadLock(100); }); t.Start(); t.Join(); Assert.IsTrue(result, "#3"); }
public void ExitWriteLock () { var v = new ReaderWriterLockSlim (); v.ExitWriteLock (); }
public static void DontReleaseWaitingReadersWhenThereAreWaitingWriters() { using(var rwls = new ReaderWriterLockSlim()) { rwls.EnterUpgradeableReadLock(); rwls.EnterWriteLock(); // Typical order of execution: 0 // Add a waiting writer var threads = new Thread[2]; using(var beforeEnterWriteLock = new ManualResetEvent(false)) { var thread = new Thread(() => { beforeEnterWriteLock.Set(); rwls.EnterWriteLock(); // Typical order of execution: 3 rwls.ExitWriteLock(); }); thread.IsBackground = true; thread.Start(); threads[0] = thread; beforeEnterWriteLock.WaitOne(); } // Add a waiting reader using(var beforeEnterReadLock = new ManualResetEvent(false)) { var thread = new Thread(() => { beforeEnterReadLock.Set(); rwls.EnterReadLock(); // Typical order of execution: 4 rwls.ExitReadLock(); }); thread.IsBackground = true; thread.Start(); threads[1] = thread; beforeEnterReadLock.WaitOne(); } // Wait for the background threads to block waiting for their locks Thread.Sleep(1000); // Typical order of execution: 1 rwls.ExitWriteLock(); // At this point there is still one reader and one waiting writer, so the reader-writer lock should not try to // release any of the threads waiting for a lock // Typical order of execution: 2 rwls.ExitUpgradeableReadLock(); // At this point, the waiting writer should be released, and the waiting reader should not foreach(var thread in threads) thread.Join(); // Typical order of execution: 5 } }
static void Main(string[] args) { rwls = new System.Threading.ReaderWriterLockSlim(); DELG Read1 = (state) => { string thread = (string)state; while (true) { rwls.EnterReadLock(); try { Console.WriteLine("Thread -> {0} -- Message -> {1}", thread, val.ToString()); } finally { rwls.ExitReadLock(); } System.Threading.Thread.Sleep(2000); } }; DELG Write1 = (state) => { string thread = (string)state; int[] tb = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 }; for (int i = 0; i < 10; i++) { rwls.EnterWriteLock(); try { val = tb[i]; Console.WriteLine("Changement de val par Thread -> {0}", thread); } finally { rwls.ExitWriteLock(); } System.Threading.Thread.Sleep(3000); } }; DELG Write2 = (state) => { string thread = (string)state; int[] tb = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; for (int i = 0; i < 10; i++) { rwls.EnterWriteLock(); try { val = tb[i]; Console.WriteLine("Changement de val par Thread -> {0}", thread); } finally { rwls.ExitWriteLock(); } System.Threading.Thread.Sleep(3000); } }; System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Read1.Invoke)); System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Read1.Invoke)); System.Threading.Thread t3 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Write1.Invoke)); System.Threading.Thread t4 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Write1.Invoke)); t1.Start((object)("T1")); t2.Start((object)("T2")); t3.Start((object)("T3")); t4.Start((object)("T4")); Console.Read(); }
static void Main(string[] args) { // create the reader-writer lock ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(); // create a cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create an array of tasks Task[] tasks = new Task[5]; for (int i = 0; i < 5; i++) { // create a new task tasks[i] = new Task(() => { while (true) { // acqure the read lock rwlock.EnterReadLock(); // we now have the lock Console.WriteLine("Read lock acquired - count: {0}", rwlock.CurrentReadCount); // wait - this simulates a read operation tokenSource.Token.WaitHandle.WaitOne(1000); // release the read lock rwlock.ExitReadLock(); Console.WriteLine("Read lock released - count {0}", rwlock.CurrentReadCount); // check for cancellation tokenSource.Token.ThrowIfCancellationRequested(); } }, tokenSource.Token); // start the new task tasks[i].Start(); } // prompt the user Console.WriteLine("Press enter to acquire write lock"); // wait for the user to press enter Console.ReadLine(); // acquire the write lock Console.WriteLine("Requesting write lock"); rwlock.EnterWriteLock(); Console.WriteLine("Write lock acquired"); Console.WriteLine("Press enter to release write lock"); // wait for the user to press enter Console.ReadLine(); // release the write lock rwlock.ExitWriteLock(); // wait for 2 seconds and then cancel the tasks tokenSource.Token.WaitHandle.WaitOne(2000); tokenSource.Cancel(); try { // wait for the tasks to complete Task.WaitAll(tasks); } catch (AggregateException) { // do nothing } // wait for input before exiting Console.WriteLine("Press enter to finish"); Console.ReadLine(); }
private void Foo3() { var concurentDictionary = new Dictionary<int, int>(); var rwLockSlim = new ReaderWriterLockSlim(); var w = new ManualResetEvent(false); int timedCalled = 0; var threads = new List<Thread>(); int j; Lazy<int> lazy = new Lazy<int>(() => { Interlocked.Increment(ref timedCalled); return 1; }); for (int i = 0; i < Environment.ProcessorCount; i++) { threads.Add(new Thread(() => { w.WaitOne(); rwLockSlim.EnterUpgradeableReadLock(); try { if (!concurentDictionary.TryGetValue(1, out j)) { rwLockSlim.EnterWriteLock(); try { Interlocked.Increment(ref timedCalled); concurentDictionary[1] = 1; } finally { rwLockSlim.ExitWriteLock(); } } } finally { rwLockSlim.ExitUpgradeableReadLock(); } })); threads.Last().Start(); } w.Set();//release all threads to start at the same time Thread.Sleep(100); Console.WriteLine(timedCalled);// output is 1 }
private void ExitWriteLock(ReaderWriterLockSlim detectorLock) { detectorLock.ExitWriteLock(); detectorLock.EnterReadLock(); detectorLock.ExitUpgradeableReadLock(); detectorLock.ExitReadLock(); }
private void Enter( ReaderWriterLockSlim @lock ) { if ( @lock.IsWriteLockHeld ) { if ( this.UseDeadlockDetection ) { MethodExecutionArgs args = new MethodExecutionArgs( @lock, Arguments.Empty ); DeadlockDetectionPolicy.ReaderWriterEnhancements.Instance.OnWriterLockExit( args ); } @lock.ExitWriteLock(); } else if ( @lock.IsWriteLockHeld ) { if ( this.UseDeadlockDetection ) { MethodInterceptionArgs args = new MethodInterceptionArgsImpl( @lock, Arguments.Empty ) { TypedBinding = WriterReadLockBinding.Instance }; DeadlockDetectionPolicy.ReaderWriterEnhancements.Instance.OnReaderLockEnter( args ); } else { @lock.EnterReadLock(); } } }
/// <summary> /// Adds an item to the threaded list /// </summary> /// <param name="item">the item to add to the end of the collection</param> public void Add(T item) { LockList.EnterWriteLock(); try { m_TList.Add(item); } finally { LockList.ExitWriteLock(); } }
public static void WriterToUpgradeableReaderChain() { using (AutoResetEvent are = new AutoResetEvent(false)) using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { rwls.EnterWriteLock(); Task t = Task.Factory.StartNew(() => { Assert.False(rwls.TryEnterUpgradeableReadLock(TimeSpan.FromMilliseconds(10))); Task.Run(() => are.Set()); // ideally this won't fire until we've called EnterReadLock, but it's a benign race in that the test will succeed either way rwls.EnterUpgradeableReadLock(); rwls.ExitUpgradeableReadLock(); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); are.WaitOne(); rwls.ExitWriteLock(); t.GetAwaiter().GetResult(); } }
public void EnterWriteLock_MultiRead() { var v = new ReaderWriterLockSlim(); int local = 10; int ready_count = 0; int entered_count = 0; const int thread_count = 10; var r = from i in Enumerable.Range(1, thread_count) select new Thread(() => { Interlocked.Increment(ref ready_count); v.EnterReadLock(); Interlocked.Increment(ref entered_count); Assert.AreEqual(11, local); }); v.EnterWriteLock(); var threads = r.ToList(); foreach (var t in threads) { t.Start(); } while (ready_count != thread_count) Thread.Sleep(10); /* Extra up to 2s of sleep to ensure all threads got the chance to enter the lock */ for (int i = 0; i < 200 && v.WaitingReadCount != thread_count; ++i) Thread.Sleep(10); local = 11; Assert.AreEqual(0, v.WaitingWriteCount, "in waiting write"); Assert.AreEqual(thread_count, v.WaitingReadCount, "in waiting read"); Assert.AreEqual(0, v.WaitingUpgradeCount, "in waiting upgrade"); v.ExitWriteLock(); foreach (var t in threads) { // Console.WriteLine (t.ThreadState); t.Join(); } }
public static void ReleaseReadersWhenWaitingWriterTimesOut() { using (var rwls = new ReaderWriterLockSlim()) { // Enter the read lock rwls.EnterReadLock(); // Typical order of execution: 0 Thread writeWaiterThread; using (var beforeTryEnterWriteLock = new ManualResetEvent(false)) { writeWaiterThread = new Thread(() => { // Typical order of execution: 1 // Add a writer to the wait list for enough time to allow successive readers to enter the wait list while this // writer is waiting beforeTryEnterWriteLock.Set(); if (rwls.TryEnterWriteLock(1000)) { // The typical order of execution is not guaranteed, as sleep times are not guaranteed. For // instance, before this write lock is added to the wait list, the two new read locks may be // acquired. In that case, the test may complete before or while the write lock is taken. rwls.ExitWriteLock(); } // Typical order of execution: 4 }); writeWaiterThread.IsBackground = true; writeWaiterThread.Start(); beforeTryEnterWriteLock.WaitOne(); } Thread.Sleep(500); // wait for TryEnterWriteLock to enter the wait list // A writer should now be waiting, add readers to the wait list. Since a read lock is still acquired, the writer // should time out waiting, then these readers should enter and exit the lock. ThreadStart EnterAndExitReadLock = () => { // Typical order of execution: 2, 3 rwls.EnterReadLock(); // Typical order of execution: 5, 6 rwls.ExitReadLock(); }; var readerThreads = new Thread[] { new Thread(EnterAndExitReadLock), new Thread(EnterAndExitReadLock) }; foreach (var readerThread in readerThreads) { readerThread.IsBackground = true; readerThread.Start(); } foreach (var readerThread in readerThreads) { readerThread.Join(); } rwls.ExitReadLock(); // Typical order of execution: 7 writeWaiterThread.Join(); } }
public TimingDetailPage() { ReaderWriterLockSlim locker = new ReaderWriterLockSlim(); IDictionary<IBoat, DateTime> times = new Dictionary<IBoat, DateTime>(); Action updateTitle = () => { var u = times.Count(t => t.Key.Number <= 0); var i = times.Count(t => t.Key.Number > 0 && t.Value > DateTime.MinValue); if(TitleUpdated != null) TitleUpdated(this, new StringEventArgs(string.Format(" - to save: {0} identified, {1} unidentified", i, u))); }; Action saveBoats = () => { TimingItemManager manager = (TimingItemManager)BindingContext; try { locker.EnterWriteLock(); manager.SaveBoat(times.Where(kvp => kvp.Value > DateTime.MinValue).Select(t => new Tuple<IBoat, DateTime, string>(t.Key, t.Value, string.Empty))); times.Clear(); updateTitle(); } finally { locker.ExitWriteLock(); } }; Action<IBoat, bool> flipflop = (IBoat boat, bool seen) => { try { locker.EnterWriteLock(); boat.Seen = seen; if(times.ContainsKey(boat)) times.Remove(boat); times.Add(boat, seen ? DateTime.Now : DateTime.MinValue); updateTitle(); } finally { locker.ExitWriteLock(); } }; Action unidentified = () => { flipflop(((TimingItemManager)BindingContext).UnidentifiedBoat, true); }; // var anchor = new ToolbarItem("Anchor", "Anchor.png", () => Debug.WriteLine("anchor"), priority: 3); var plus = new ToolbarItem("Add", "Add.png", () => unidentified(), priority: 3); var sync = new ToolbarItem("Sync", "Syncing.png", saveBoats, priority: 2); ToolbarItem more=null; Action refreshToolbar = () => { ToolbarItems.Clear(); ToolbarItems.Add(plus); ToolbarItems.Add(sync); ToolbarItems.Add(more); }; more = new ToolbarItem("More", "More.png", refreshToolbar, priority: 1); refreshToolbar(); var listView = new ListView(); listView.SetBinding (ListView.ItemsSourceProperty, "Unfinished"); Action<IBoat> press = async (IBoat boat) => { string pin = "Pin to top"; string send = "Send to End"; var sheet = await DisplayActionSheet (string.Format("Boat {0}: Send to ... ?", boat.Number), "Cancel", null, pin, send); if(sheet == pin) { ToolbarItem item = null; Action action = () => { flipflop(boat, true); ToolbarItems.Remove(item); }; item = new ToolbarItem(boat.Number.ToString(), null, action, priority: -1); ToolbarItems.Add(item); } if(sheet == send) { boat.End = true; } Debug.WriteLine("Action: " + sheet); }; listView.ItemTemplate = new DataTemplate(() => new UnseenCell(press)); listView.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => { Debug.WriteLine("underlying change"); }; listView.ItemSelected += (object sender, SelectedItemChangedEventArgs e) => { if(e.SelectedItem == null) return; IBoat boat = (IBoat)e.SelectedItem; flipflop(boat, !boat.Seen); listView.SelectedItem = null; }; SearchBar searchBar = new SearchBar { Placeholder = "Filter list", }; searchBar.TextChanged += (object sender, TextChangedEventArgs e) => { TimingItemManager manager = (TimingItemManager)BindingContext; manager.Filter(searchBar.Text); }; Content = new StackLayout () { Children={searchBar, listView} }; // idea: hide a non-starter }
public void ClearAll() { _threadLock.EnterWriteLock(); foreach (var cell in _cells) { _cellPool.Store(cell.Value); } _cellKeys.Clear(); _cells.Clear(); _oldPlayerOccupied.Clear(); _oldPlayerWalkable.Clear(); CellsCount = 0; _threadLock.ExitWriteLock(); }
public async Task ProcessCrawlingQueueAsync(CrawlingQueue crawlingQueue) { _crawlingParameters.CancellationTokenSource.Token.Register(() => crawlingQueue.QueueCancellationTokenSource.Cancel() ); var tasksLock = new System.Threading.ReaderWriterLockSlim(); var tasks = new HashSet <Task>(); var queueItemsProcessingSemaphore = new SemaphoreSlim(crawlingQueue.CrawlingConfiguration.MaxSimmultaneousQueueItemsProcessed / 2, crawlingQueue.CrawlingConfiguration.MaxSimmultaneousQueueItemsProcessed); while (await queueItemsProcessingSemaphore.WaitAsync(crawlingQueue.CrawlingConfiguration.MaxTimeToProcessOneQueueItem)) { if (crawlingQueue.QueueCancellationTokenSource.IsCancellationRequested) { await Task.WhenAll(tasks.ToArray()); // TODO: Move remaining items from local queue to the distributed queue // TODO: Figure out how to filter out duplicates from the queue? Or should we? // We will probably have to resort to known urls-based duplicates check // Because otherwise we will drown in failing sql queries on multiplie machines Trace.TraceWarning("ProcessCrawlingQueueAsync: Queue cancellation requested. Preventing dequeing of new elements. Processing will be shut down after currently executing items are complete."); break; } var queueItem = await crawlingQueue.DequeueAsync(); if (queueItem == null) // Both Local and Proxy queues are depleted { // NOTE: If Queue is depleted, we must wait until all running tasks are executed, because they might add new items to queue await Task.WhenAll(tasks.ToArray()); // wait for all queue proxies to complete fetching items // TODO: consider locking (multithreading scenario) var queueProxiesPending = crawlingQueue.QueueProxies.Where(queueProxy => queueProxy.IsPending()).ToArray(); if (queueProxiesPending.Length > 0) { continue; } if (crawlingQueue.LocalQueue.Count > 0) { continue; } break; } if (!await _crawlingEventInterceptorManager.OnAfterDequeueAsync(queueItem)) { // If interceptor returns false, means it's an instruction to ignore this item; continue; } tasksLock.EnterWriteLock(); queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.Downloading); tasks.Add(System.Threading.Tasks.TaskExtensions.Unwrap( CrawlAsync(queueItem.ResourceLink) .ContinueWith(async task => { tasksLock.EnterWriteLock(); tasks.Remove(task); // to avoid infinite bloating of the collection tasksLock.ExitWriteLock(); try { queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.Downloaded); if (task.Status == TaskStatus.RanToCompletion) { var resourceContentUnits = task.Result; var httpResultUnit = resourceContentUnits.OfType <HttpResultUnit>().Single(); queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.Processing); var resourceContentUnitsProcessingCountdown = new AsyncCountdownEvent(resourceContentUnits.Count); // Process resource content units extracted from Response foreach (var resourceContentUnit in resourceContentUnits) { switch (resourceContentUnit) { case ExtractedLinksUnit extractedLinksUnit: if (extractedLinksUnit.ExtractedLinks.Count > 0) { var linksProcessingCountdown = new AsyncCountdownEvent(extractedLinksUnit.ExtractedLinks.Count); foreach (var extractedLink in extractedLinksUnit.ExtractedLinks) { var crawlingQueueItem = new CrawlingQueueItem(extractedLink); // Do not enqueue item if prevented by any interceptor if (!await _crawlingEventInterceptorManager.OnBeforeEnqueueAsync(crawlingQueueItem)) { continue; } crawlingQueueItem.ProcessingCompleted += () => linksProcessingCountdown.AddCount(1) ; crawlingQueue.Enqueue(crawlingQueueItem); } // Wait while all links are processed before releasing the content units semaphore and set Status = Processed for parent linksProcessingCountdown.WaitAsync() .ContinueWith(linksProcessingTask => resourceContentUnitsProcessingCountdown.AddCount(1) ); } else { resourceContentUnitsProcessingCountdown.AddCount(1); } // Set Processed status when all extracted links are processed break; case ExtractedDataUnit extractedDataUnit: if (!await _crawlingEventInterceptorManager.OnDataDocumentDownloadedAsync( queueItem.ResourceLink, // May be a DocumentLink, or a FrameLink. Not quite intuitive and probably requires redesign. extractedDataUnit, httpResultUnit )) { // If any of interceptors failed to process the download result, // AND failed to store download result for later processing // we must re-enqueue the item, in order to ensure the results are not lost for good // We ignore the item and log the error. Chances are we couldn't process the item for a reason. And repeating would just make it stuck infinitely (re-downloading and re-processing) // (WAS) we must re-enqueue the item, in order to ensure the results are not lost for good //crawlingQueue.EnqueueAsync(queueItem); } resourceContentUnitsProcessingCountdown.Signal(); break; case DownloadedFilesUnit downloadedFileUnit: // If download file is a result of redirection, // we must either explicitly declare that we're expecting a file, or throw a processing exception var fileLink = queueItem.ResourceLink as FileLink; if (fileLink == null) { Trace.TraceError($"ProcessCrawlingQueueAsync: Downloaded file unit. Resource link is of type {queueItem.ResourceLink.GetType().Name}, expecting FileLink. Preventing processing."); break; } if (!await _crawlingEventInterceptorManager.OnFileDownloadedAsync( fileLink, downloadedFileUnit, httpResultUnit )) { // If any of interceptors failed to process the download result, // AND failed to store download result for later processing.... // We ignore the item and log the error. Chances are we couldn't process the item for a reason. And repeating would just make it stuck infinitely (re-downloading and re-processing) // (WAS) we must re-enqueue the item, in order to ensure the results are not lost for good //crawlingQueue.EnqueueAsync(queueItem); } resourceContentUnitsProcessingCountdown.Signal(); break; case HttpResultUnit httpResultUnitStub: // TODO: Determine what we should do if HTTP download failed. Either re-enqueue or ignore, or alert/do something else switch (httpResultUnitStub.HttpStatus) { //case HttpStatusCode.InternalServerError: // it's likely to repeat within the same run case HttpStatusCode.GatewayTimeout: case HttpStatusCode.RequestTimeout: queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.NotLinked); crawlingQueue.Enqueue(queueItem); // Trying to recrawl item if it failed for some intermitent reason break; default: // We need to invoke ProcessingCompleted only after Data and Links extracted are really processed. //queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.ProcessingCompleted); break; } resourceContentUnitsProcessingCountdown.Signal(); break; default: throw new NotSupportedException(); } } // Do not actually wait for related resources processing completion. // Those might be extracted links or files. No need to hold queue resources while linked units are downloaded // Set Processed status after all content units were registered and interceptors triggered await resourceContentUnitsProcessingCountdown.WaitAsync() .ContinueWith(resourceContentUnitsProcessingTask => queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.Processed) ); } else { Trace.TraceError("CrawlAsync: Failed for queue item {0} with exception [{1}]", queueItem.ResourceLink, task.Exception); } } finally { queueItemsProcessingSemaphore.Release(); } }) ) ); tasksLock.ExitWriteLock(); } await Task.WhenAll(tasks.ToArray()); }
public void RecursiveEnterExitWriteTest() { var v = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); v.EnterWriteLock(); v.EnterWriteLock(); v.EnterWriteLock(); Assert.IsTrue(v.IsWriteLockHeld); Assert.AreEqual(3, v.RecursiveWriteCount); v.ExitWriteLock(); v.ExitWriteLock(); Assert.IsTrue(v.IsWriteLockHeld); Assert.AreEqual(1, v.RecursiveWriteCount); }
/// <summary> /// Lock our inventory list for reading (many can read, one can write) /// </summary> public void LockItemsForRead(bool locked) { if (locked) { if (m_itemLock.IsWriteLockHeld && LockedByThread != null) { if (!LockedByThread.IsAlive) { //Locked by dead thread, reset. m_itemLock = new System.Threading.ReaderWriterLockSlim(); } } if (m_itemLock.RecursiveReadCount > 0) { m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); try { // That call stack is useful for end users only. RealProgrammers need a full dump. Commented. // StackTrace stackTrace = new StackTrace(); // get call stack // StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) // // // write call stack method names // foreach (StackFrame stackFrame in stackFrames) // { // m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name // } // The below is far more useful // System.Console.WriteLine("------------------------------------------"); // System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); // System.Console.WriteLine("------------------------------------------"); // foreach (KeyValuePair<Thread, string> kvp in ReadLockers) // { // System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name); // System.Console.WriteLine("------------------------------------------"); // } } catch { } m_itemLock.ExitReadLock(); } if (m_itemLock.RecursiveWriteCount > 0) { m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); // try // { // System.Console.WriteLine("------------------------------------------"); // System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); // System.Console.WriteLine("------------------------------------------"); // System.Console.WriteLine("Locker's call stack:\n" + WriterStack); // System.Console.WriteLine("------------------------------------------"); // } // catch // {} m_itemLock.ExitWriteLock(); } while (!m_itemLock.TryEnterReadLock(60000)) { m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); //if (m_itemLock.IsWriteLockHeld) //{ m_itemLock = new System.Threading.ReaderWriterLockSlim(); // System.Console.WriteLine("------------------------------------------"); // System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); // System.Console.WriteLine("------------------------------------------"); // System.Console.WriteLine("Locker's call stack:\n" + WriterStack); // System.Console.WriteLine("------------------------------------------"); // LockedByThread = null; // ReadLockers.Clear(); //} } // ReadLockers[Thread.CurrentThread] = Environment.StackTrace; } else { if (m_itemLock.RecursiveReadCount > 0) { m_itemLock.ExitReadLock(); } // if (m_itemLock.RecursiveReadCount == 0) // ReadLockers.Remove(Thread.CurrentThread); } }
public void RecursiveWriteUpgradeTest() { ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); rwlock.EnterWriteLock(); Assert.IsTrue(rwlock.IsWriteLockHeld); rwlock.EnterUpgradeableReadLock(); Assert.IsTrue(rwlock.IsUpgradeableReadLockHeld); rwlock.ExitUpgradeableReadLock(); Assert.IsFalse(rwlock.IsUpgradeableReadLockHeld); Assert.IsTrue(rwlock.IsWriteLockHeld); rwlock.ExitWriteLock(); Assert.IsFalse(rwlock.IsWriteLockHeld); rwlock.EnterWriteLock(); Assert.IsTrue(rwlock.IsWriteLockHeld); }
public void EnterWriteLockWhileInUpgradeAndOtherWaiting () { var v = new ReaderWriterLockSlim (); var task2 = new Task(() => { v.EnterWriteLock(); v.ExitWriteLock(); }); var task1 = new Task(() => { v.EnterUpgradeableReadLock (); task2.Start (); Thread.Sleep (100); v.EnterWriteLock (); v.ExitWriteLock (); v.ExitUpgradeableReadLock (); }); task1.Start (); Assert.IsTrue (task1.Wait (500)); }
public void EnterWriteLock () { var v = new ReaderWriterLockSlim (); v.EnterWriteLock (); Assert.IsTrue (v.IsWriteLockHeld, "A"); Assert.AreEqual (1, v.RecursiveWriteCount, "A1"); Assert.AreEqual (0, v.RecursiveReadCount, "A2"); Assert.AreEqual (0, v.RecursiveUpgradeCount, "A3"); Assert.AreEqual (0, v.WaitingReadCount, "A4"); Assert.AreEqual (0, v.WaitingUpgradeCount, "A5"); Assert.AreEqual (0, v.WaitingWriteCount, "A6"); v.ExitWriteLock (); v.EnterWriteLock (); Assert.IsTrue (v.IsWriteLockHeld, "B"); Assert.AreEqual (1, v.RecursiveWriteCount, "B1"); Assert.AreEqual (0, v.RecursiveReadCount, "B2"); Assert.AreEqual (0, v.RecursiveUpgradeCount, "B3"); Assert.AreEqual (0, v.WaitingReadCount, "B4"); Assert.AreEqual (0, v.WaitingUpgradeCount, "B5"); Assert.AreEqual (0, v.WaitingWriteCount, "B6"); v.ExitWriteLock (); }
public static void DeadlockAvoidance() { using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim()) { rwls.EnterReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock()); Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock()); Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock()); rwls.ExitReadLock(); rwls.EnterUpgradeableReadLock(); rwls.EnterReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock()); rwls.ExitReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock()); rwls.EnterWriteLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock()); rwls.ExitWriteLock(); rwls.ExitUpgradeableReadLock(); rwls.EnterWriteLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterReadLock()); Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock()); Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock()); rwls.ExitWriteLock(); } using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion)) { rwls.EnterReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterWriteLock()); rwls.EnterReadLock(); Assert.Throws<LockRecursionException>(() => rwls.EnterUpgradeableReadLock()); rwls.ExitReadLock(); rwls.ExitReadLock(); rwls.EnterUpgradeableReadLock(); rwls.EnterReadLock(); rwls.EnterUpgradeableReadLock(); rwls.ExitUpgradeableReadLock(); rwls.EnterReadLock(); rwls.ExitReadLock(); rwls.ExitReadLock(); rwls.EnterWriteLock(); rwls.EnterWriteLock(); rwls.ExitWriteLock(); rwls.ExitWriteLock(); rwls.ExitUpgradeableReadLock(); rwls.EnterWriteLock(); rwls.EnterReadLock(); rwls.ExitReadLock(); rwls.EnterUpgradeableReadLock(); rwls.ExitUpgradeableReadLock(); rwls.EnterWriteLock(); rwls.ExitWriteLock(); rwls.ExitWriteLock(); } }
public void EnterWriteLock_After_ExitUpgradeableReadLock () { var v = new ReaderWriterLockSlim (); v.EnterUpgradeableReadLock (); Assert.IsTrue (v.TryEnterWriteLock (100)); v.ExitWriteLock (); v.ExitUpgradeableReadLock (); Assert.IsTrue (v.TryEnterWriteLock (100)); v.ExitWriteLock (); }
public static void InvalidExits(LockRecursionPolicy policy) { using (ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(policy)) { Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock()); rwls.EnterReadLock(); Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock()); rwls.ExitReadLock(); rwls.EnterUpgradeableReadLock(); Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock()); rwls.ExitUpgradeableReadLock(); rwls.EnterWriteLock(); Assert.Throws<SynchronizationLockException>(() => rwls.ExitReadLock()); Assert.Throws<SynchronizationLockException>(() => rwls.ExitUpgradeableReadLock()); rwls.ExitWriteLock(); using (Barrier barrier = new Barrier(2)) { Task t = Task.Factory.StartNew(() => { rwls.EnterWriteLock(); barrier.SignalAndWait(); barrier.SignalAndWait(); rwls.ExitWriteLock(); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); barrier.SignalAndWait(); Assert.Throws<SynchronizationLockException>(() => rwls.ExitWriteLock()); barrier.SignalAndWait(); t.GetAwaiter().GetResult(); } } }
private static void FreeWriterLock(ReaderWriterLockSlim oLock) { oLock.ExitWriteLock(); }
public static void ReleaseWriteLock(ReaderWriterLockSlim locks) { if (locks.IsWriteLockHeld) locks.ExitWriteLock(); }