static void Main(string[] args) { var t1 = Task.Factory.StartNew(state => { //lock (_sync1) using (var l1 = LeveledLock.Acquire(_sync1)) { Console.WriteLine("L1: Level={0}", l1.Level); Thread.Sleep(100); //lock (_sync2) using (var l2 = LeveledLock.Acquire(_sync2)) { Console.WriteLine("L2: Level={0}", l2.Level); Console.WriteLine("Done 1"); } } }, "T1"); //t1.Wait(); var t2 = Task.Factory.StartNew(state => { //lock (_sync2) using (var l2 = LeveledLock.Acquire(_sync2)) { Console.WriteLine("L2: Level={0}", l2.Level); Thread.Sleep(100); //lock (_sync1) using (var l1 = LeveledLock.Acquire(_sync1)) { Console.WriteLine("L1: Level={0}", l1.Level); Console.WriteLine("Done 1"); } } }, "T2"); // using continuation to write errors t1.ContinueWith(t => Console.WriteLine("{0}: {1}", t.AsyncState, t.Exception.InnerExceptions[0].Message), TaskContinuationOptions.OnlyOnFaulted); t2.ContinueWith(t => Console.WriteLine("{0}: {1}", t.AsyncState, t.Exception.InnerExceptions[0].Message), TaskContinuationOptions.OnlyOnFaulted); // using continuation to write complete t1.ContinueWith(t => Console.WriteLine("{0} Complete", t.AsyncState), TaskContinuationOptions.NotOnFaulted); t2.ContinueWith(t => Console.WriteLine("{0} Complete", t.AsyncState), TaskContinuationOptions.NotOnFaulted); Console.WriteLine("Done"); Console.ReadKey(); }
public static LeveledLock Acquire(object sync) { LeveledLock leveledLock; lock (_localSync) { bool isAdded; if (_locks.ContainsKey(sync)) { leveledLock = _locks[sync]; leveledLock.RefCount += 1; // used for disposal isAdded = false; } else { leveledLock = new LeveledLock(sync); _locks.Add(sync, leveledLock); // set the lock leveling isAdded = true; } if (leveledLock.Level > _currentGlobalLevel) // check for potential deadlock { throw new ThreadStateException("Potential deadlock"); } if (isAdded) // if the { _currentGlobalLevel--; leveledLock.Level = _currentGlobalLevel; } } Monitor.Enter(sync); return(leveledLock); }