public void OnEnter(MethodInterceptionArgs args)
            {
                DeadlockMonitor.ExecuteAction(
                    () => LockAspectHelper.NoTimeoutAcquire(
                        () => DeadlockMonitor.EnterWaiting(args.Arguments[0], ResourceType.Lock),
                        timeout =>
                {
                    bool lockTaken = false;
                    try
                    {
                        Monitor.TryEnter(args.Arguments[0], timeout, ref lockTaken);
                    }
                    finally
                    {
                        if (args.Arguments.Count > 1)
                        {
                            args.Arguments.SetArgument(1, lockTaken);
                        }
                    }

                    return(lockTaken);
                },
                        () => DeadlockMonitor.ConvertWaitingToAcquired(args.Arguments[0], ResourceType.Lock),
                        () => DeadlockMonitor.ExitWaiting(args.Arguments[0], ResourceType.Lock)));
            }
            public void OnWaitOne(MethodInterceptionArgs args)
            {
                DeadlockMonitor.ExecuteAction(
                    () =>
                {
                    if (!(args.Instance is Mutex))
                    {
                        return;
                    }

                    if (args.Arguments.Count == 0 || args.Arguments[0] is bool ||
                        (args.Arguments[0] is int && (int)args.Arguments[0] == Timeout.Infinite))
                    {
                        Mutex mutex      = args.Instance as Mutex;
                        bool?exitContext = args.Arguments.Count > 0 ? (bool?)args.Arguments[0] : null;
                        LockAspectHelper.NoTimeoutAcquire(
                            () => DeadlockMonitor.EnterWaiting(mutex, ResourceType.Lock),
                            timeout =>
                            exitContext.HasValue
                                        ? mutex.WaitOne(timeout, exitContext.Value)
                                        : mutex.WaitOne(timeout),
                            () => DeadlockMonitor.ConvertWaitingToAcquired(mutex, ResourceType.Lock),
                            () => DeadlockMonitor.ExitWaiting(mutex, ResourceType.Lock));
                    }
                    else
                    {
                        args.Proceed();

                        if ((bool)args.ReturnValue)
                        {
                            DeadlockMonitor.EnterAcquired(args.Instance, ResourceType.Lock);
                        }
                    }
                });
            }
            internal static void OnEnter(MethodInterceptionArgs args, ResourceType type, bool addAcquierdEdge = true)
            {
                Func <int, bool> acquireLock;

                if (args.Arguments.Count == 0)   // when arguments count == 0 it must be ReaderWriterLockSlim
                {
                    acquireLock = timeout =>
                    {
                        bool lockTaken;
                        ReaderWriterLockSlim rwl = (ReaderWriterLockSlim)args.Instance;
                        switch (type)
                        {
                        case ResourceType.Read:
                            lockTaken = rwl.TryEnterReadLock(timeout);
                            break;

                        case ResourceType.Write:
                            lockTaken = rwl.TryEnterWriteLock(timeout);
                            break;

                        case ResourceType.UpgradeableRead:
                            lockTaken = rwl.TryEnterUpgradeableReadLock(timeout);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                        return(lockTaken);
                    };
                }
                else
                {
                    acquireLock = timeout =>
                    {
                        bool lockTaken;
                        args.Arguments.SetArgument(0, timeout);

                        try
                        {
                            args.Proceed();
                            lockTaken = true;
                        }
                        catch (ApplicationException)
                        {
                            lockTaken = false;
                        }
                        return(lockTaken);
                    };
                }

                LockAspectHelper.NoTimeoutAcquire(
                    () => DeadlockMonitor.EnterWaiting(args.Instance, ResourceType.Read),
                    acquireLock,
                    addAcquierdEdge ? () => DeadlockMonitor.ConvertWaitingToAcquired(args.Instance, ResourceType.Read) : (Action)(() => { }),
                    () => DeadlockMonitor.ExitWaiting(args.Instance, ResourceType.Read));
            }
            public void OnWaitAll(MethodInterceptionArgs args)
            {
                DeadlockMonitor.ExecuteAction(
                    () =>
                {
                    WaitHandle[] waitHandles = (WaitHandle[])args.Arguments[0];

                    if (args.Arguments.Count == 1 ||
                        (args.Arguments[0] is int && (int)args.Arguments[0] == Timeout.Infinite))
                    {
                        bool?exitContext = args.Arguments.Count > 2 ? (bool?)args.Arguments[2] : null;

                        LockAspectHelper.NoTimeoutAcquire(
                            () =>
                        {
                            foreach (Mutex mutex in waitHandles.OfType <Mutex>())
                            {
                                DeadlockMonitor.EnterWaiting(mutex, ResourceType.Lock);
                            }
                        },
                            timeout =>
                            exitContext.HasValue
                                        ? WaitHandle.WaitAll(waitHandles, timeout, exitContext.Value)
                                        : WaitHandle.WaitAll(waitHandles, timeout),
                            () =>
                        {
                            foreach (Mutex mutex in waitHandles.OfType <Mutex>())
                            {
                                DeadlockMonitor.ConvertWaitingToAcquired(mutex, ResourceType.Lock);
                            }
                        },
                            () =>
                        {
                            foreach (Mutex mutex in waitHandles.OfType <Mutex>())
                            {
                                DeadlockMonitor.ExitWaiting(mutex, ResourceType.Lock);
                            }
                        });
                    }
                    else
                    {
                        args.Proceed();

                        if ((bool)args.ReturnValue)
                        {
                            foreach (Mutex mutex in waitHandles.OfType <Mutex>())
                            {
                                DeadlockMonitor.EnterAcquired(mutex, ResourceType.Lock);
                            }
                        }
                    }
                });
            }
            public void OnTryEnter(MethodInterceptionArgs args)
            {
                DeadlockMonitor.ExecuteAction(
                    () =>
                {
                    if (args.Arguments[0] is int && (int)args.Arguments[0] == -1)
                    {
                        LockAspectHelper.NoTimeoutAcquire(
                            () => DeadlockMonitor.EnterWaiting(args.Arguments[0], ResourceType.Lock),
                            timeout =>
                        {
                            bool lockTaken = false;
                            try
                            {
                                Monitor.TryEnter(args.Arguments[0], timeout, ref lockTaken);
                            }
                            finally
                            {
                                if ((args.Arguments.Count == 2 && args.Arguments[1] is bool) ||
                                    (args.Arguments.Count == 3 && args.Arguments[2] is bool))
                                {
                                    args.Arguments.SetArgument(args.Arguments.Count - 1, lockTaken);
                                }
                            }


                            return(lockTaken);
                        },
                            () => DeadlockMonitor.ConvertWaitingToAcquired(args.Arguments[0], ResourceType.Lock),
                            () => DeadlockMonitor.ExitWaiting(args.Arguments[0], ResourceType.Lock));
                    }
                    else
                    {
                        try
                        {
                            bool lockTaken;

                            {
                                DeadlockMonitor.EnterWaiting(args.Arguments[0], ResourceType.Lock);
                                args.Proceed();

                                if ((args.Arguments.Count == 2 && args.Arguments[1] is bool) ||
                                    (args.Arguments.Count == 3 && args.Arguments[2] is bool))
                                {
                                    lockTaken = (bool)args.Arguments.GetArgument(args.Arguments.Count - 1);
                                }
                                else
                                {
                                    lockTaken = (bool)args.ReturnValue;
                                }
                            }

                            if (lockTaken)
                            {
                                DeadlockMonitor.ConvertWaitingToAcquired(args.Arguments[0], ResourceType.Lock);
                            }
                            else
                            {
                                DeadlockMonitor.ExitWaiting(args.Arguments[0], ResourceType.Lock);
                            }
                        }
                        catch (Exception)
                        {
                            DeadlockMonitor.ExitWaiting(args.Arguments[0], ResourceType.Lock);
                            throw;
                        }
                    }
                });
            }