public RootLock(BPlusTree <TKey, TValue> tree, LockType type, bool exclusiveTreeAccess, string methodName) { tree.NotDisposed(); _tree = tree; _type = type; _version = type == LockType.Read ? tree._storage.CurrentVersion : null; _methodName = methodName; _exclusive = exclusiveTreeAccess; _locked = _exclusive ? _tree._selfLock.TryWrite(tree._options.LockTimeout) : _tree._selfLock.TryRead(tree._options.LockTimeout); LockTimeoutException.Assert(_locked); try { Pin = _tree._storage.LockRoot(type); } catch { if (_exclusive) { _tree._selfLock.ReleaseWrite(); } else { _tree._selfLock.ReleaseRead(); } throw; } }
/// <summary> /// Disposes of this lock. /// </summary> public void Dispose() { // Owning thread is done. #if DEBUGLOCKS try { //This shouldn't throw an exception. LockTimeoutException.ReportStackTraceIfError(target); } finally { //But just in case... Monitor.Exit(target); } #else Monitor.Exit(target); #endif #if DEBUGLOCKS // It's a bad error if someone forgets to call Dispose, // so in Debug builds, we put a finalizer in to detect // the error. If Dispose is called, we suppress the // finalizer. GC.SuppressFinalize(leakDetector); #endif Thread.EndCriticalRegion(); }
public void Test1() { try { Exception e = new LockTimeoutException("This is a test exception"); e.Data.Add("Platform", "Bing"); MockExceptionThrower mock = new MockExceptionThrower(); mock.ExceptionToThrow = e; mock.Depth = 20; mock.Throw(); } catch (Exception ex) { ExceptionFormatter formater = new ExceptionFormatter("Test Application", "Exception Report Header", "Location: Home Office", "Version: 3.4"); formater.WriteExceptionHash = true; formater.WriteLoadedAssemblies = true; string message = formater.Generate(ex); Assert.IsNotNull(message); } }