EnterWriteLock() public method

public EnterWriteLock ( ) : void
return void
Beispiel #1
0
        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);
        }
Beispiel #2
0
        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();
     }
 }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
 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();
                }
            }
        }
Beispiel #7
0
        /// <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();
            }
        }
Beispiel #8
0
        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();
        }
        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();
                }
            });

        }
Beispiel #10
0
        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();
            }
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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 SlimWriteLockHolder(ReaderWriterLockSlim locker, bool waitForLock)
		{
			this.locker = locker;
			if(waitForLock)
			{
				locker.EnterWriteLock();
				lockAcquired = true;
				return;
			}
			lockAcquired = locker.TryEnterWriteLock(0);
		}
        public static LockHandle Write(this ReaderWriterLockSlim self)
        {
            Check.Self(self);
            if (self.IsWriteLockHeld)
            {
                return(new LockHandle());
            }

            self.EnterWriteLock();
            return(new LockHandle(self, LockHandle.LockType.Write));
        }
        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();
            }
        }
Beispiel #16
0
 private static void AtomWrite(ReaderWriterLockSlim readerWriterLockSlim, Action action)
 {
     readerWriterLockSlim.EnterWriteLock();
     try
     {
         action();
     }
     finally
     {
         readerWriterLockSlim.ExitWriteLock();
     }
 }
        public ReadWriteLock(ReaderWriterLockSlim lockObject, bool forWrite)
        {
            if (lockObject == null)
                throw new ArgumentNullException("lockObject");
            this.lockObject = lockObject;
            this.forWrite = forWrite;

            if (forWrite)
                lockObject.EnterWriteLock();
            else
                lockObject.EnterReadLock();
        }
        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();
     }
 }
 // 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();
 }
Beispiel #22
0
        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++;
                    }
                });
                });
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ReadLock"/> class.
        /// </summary>
        /// <param name="readerWriterLockSlim">The reader writer lock slim.</param>
        public NestableWriteLock(ReaderWriterLockSlim readerWriterLockSlim)
        {
            // Keep track of the lock since we'll need it to release the lock.
            this.readerWriterLockSlim = readerWriterLockSlim;

            // If we already have a read or write lock, we don't do anything.
            if (readerWriterLockSlim.IsWriteLockHeld)
            {
                lockAcquired = false;
            }
            else
            {
                readerWriterLockSlim.EnterWriteLock();
                lockAcquired = true;
            }
        }
Beispiel #25
0
 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();
			   });
		}
Beispiel #27
0
 public LockExtend(ReaderWriterLockSlim slim, LockMode mode)
 {
     _Slim = slim;
     this._Mode = mode;
     switch(mode)
     {
         case LockMode.Write:
             slim.EnterWriteLock();
             break;
         case LockMode.Read:
             slim.EnterReadLock();
             break;
         case LockMode.UpgradeableRead:
             slim.EnterUpgradeableReadLock();
             break;
     }
 }
        public ScopedReaderWriterLock(ReaderWriterLockSlim readerWriterLock, bool readOnly = true)
        {
            if (_readerWriterLock == null)
            {
                throw new ArgumentNullException(nameof(readerWriterLock));
            }

            _readerWriterLock = readerWriterLock;
            _readOnly = readOnly;

            if (_readOnly)
            {
                _readerWriterLock.EnterReadLock();
            }
            else
            {
                _readerWriterLock.EnterWriteLock();
            }
        }
Beispiel #29
0
        /// <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 XXX()
        {
            //var l = new ReaderWriterLockSlimEx();

            //using (l.AcquireReadLock())
            //{
            //    // access lock here so it's not optimized-away after release build
            //    Assert.IsNotNull(l);
            //}

            var l = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);

            l.EnterWriteLock();

            Assert.IsTrue(l.IsWriteLockHeld);

            Task.Factory.StartNew(() =>
            {
                Assert.IsFalse(l.IsWriteLockHeld);
            }).Wait();
            
        }
Beispiel #31
0
		public void Dispose_Errors ()
		{
			var v = new ReaderWriterLockSlim ();
			v.Dispose ();

			try {
				v.EnterUpgradeableReadLock ();
				Assert.Fail ("1");
			} catch (ObjectDisposedException) {
			}

			try {
				v.EnterReadLock ();
				Assert.Fail ("2");
			} catch (ObjectDisposedException) {
			}

			try {
				v.EnterWriteLock ();
				Assert.Fail ("3");
			} catch (ObjectDisposedException) {
			}
		}
        public static void Dispose()
        {
            ReaderWriterLockSlim rwls;

            rwls = new ReaderWriterLockSlim();
            rwls.Dispose();
            Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterReadLock(0));
            Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterUpgradeableReadLock(0));
            Assert.Throws<ObjectDisposedException>(() => rwls.TryEnterWriteLock(0));
            rwls.Dispose();

            for (int i = 0; i < 3; i++)
            {
                rwls = new ReaderWriterLockSlim();
                switch (i)
                {
                    case 0: rwls.EnterReadLock(); break;
                    case 1: rwls.EnterUpgradeableReadLock(); break;
                    case 2: rwls.EnterWriteLock(); break;
                }
                Assert.Throws<SynchronizationLockException>(() => rwls.Dispose());
            }
        }
Beispiel #33
0
		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 ();
			}
		}
Beispiel #34
0
		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 ();
		}
Beispiel #35
0
		public void EnterWriteLock_NoRecursionError ()
		{
			var v = new ReaderWriterLockSlim ();
			v.EnterWriteLock ();
			Assert.AreEqual (1, v.RecursiveWriteCount);

			try {
				v.EnterWriteLock ();
				Assert.Fail ("1");
			} catch (LockRecursionException) {
			}

			try {
				v.EnterReadLock ();
				Assert.Fail ("2");
			} catch (LockRecursionException) {
			}
		}
        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 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 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();
                }
            }
        }
 public void Dispose_WithWriteLock()
 {
     var rwl = new ReaderWriterLockSlim();
     rwl.EnterWriteLock();
     try
     {
         rwl.Dispose();
         Assert.Fail("1");
     }
     catch (SynchronizationLockException)
     {
     }
 }
Beispiel #40
0
 public void Refresh()
 {
     m_ReadWriterLock.EnterWriteLock();
     m_VisibleQueueStatus = VisibleQueueStatus.Refresh;
     m_ReadWriterLock.ExitWriteLock();
 }
Beispiel #41
0
        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 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 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 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 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();
             }));
     }
 }
Beispiel #46
0
		public void RecursiveReadPlusWriteLockTest ()
		{
			var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);

			try {
				v.EnterReadLock ();
				v.EnterWriteLock ();
				Assert.Fail ("1");
			} catch (LockRecursionException ex) {
				Assert.IsNotNull (ex, "#1");
			}
		}
Beispiel #47
0
		public void RecursiveWritePropertiesTest ()
		{
			var v = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);

			v.EnterWriteLock ();
			v.EnterWriteLock ();

			Assert.AreEqual (true, v.IsWriteLockHeld, "#1a");
			Assert.AreEqual (2, v.RecursiveWriteCount, "#3a");

			bool wLock = false;
			int rWrite = -1;

			Thread t = new Thread ((_) => {
					wLock = v.IsWriteLockHeld;
					rWrite = v.RecursiveWriteCount;
				});

			t.Start ();
			t.Join ();

			Assert.AreEqual (false, wLock, "#1b");
			Assert.AreEqual (0, rWrite, "#3b");
		}
        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 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);
        }
        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 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
            }
        }
Beispiel #52
0
        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();
        }