internal void DetectDeadlocks(Thread startThread) { lock (_deadlockDetectionLock) { _graph.FindCycles(new Node(startThread, LockType.Thread), out var cycles); if (!cycles.Any()) { return; } var info = new DeadlockInfo { Threads = cycles .Where(e => e.Prev.LockType == LockType.Thread) .Select(e => e.Prev.MonitorObject) .OfType <Thread>() .Union( cycles .Where(e => e.Next.LockType == LockType.Thread) .Select(e => e.Next.MonitorObject) .OfType <Thread>() ).ToList(), Message = string.Join("; ", cycles.Select(c => c.ToString())) }; foreach (var thread in info.Threads.Where(t => t != Thread.CurrentThread)) { _pendingDeadlockExceptions .GetValue(thread, t => new ConcurrentBag <DeadlockException>()) .Add(new DeadlockException(info)); } throw new DeadlockException(info); } }
public DeadlockException(DeadlockInfo deadlockInfo) : base(deadlockInfo.Message) { DeadlockInfo = deadlockInfo; }