Index: src/Common/DelftTools.Utils/Aop/InvokeRequiredAttribute.cs =================================================================== diff -u -r8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9 -r5fc71a385897af92ccb092f2f969b5709afab85a --- src/Common/DelftTools.Utils/Aop/InvokeRequiredAttribute.cs (.../InvokeRequiredAttribute.cs) (revision 8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9) +++ src/Common/DelftTools.Utils/Aop/InvokeRequiredAttribute.cs (.../InvokeRequiredAttribute.cs) (revision 5fc71a385897af92ccb092f2f969b5709afab85a) @@ -19,7 +19,16 @@ private static int pendingInvokes; //number of invokes pending (global!) private static readonly object InvokeLock = new object(); //object to lock on private static readonly ManualResetEvent ZeroPendingInvokes = new ManualResetEvent(true); //true/signalled if there are no invokes pending - + + /// + /// Call this method with a using statement around the content of the Dispose method you want to protected. + /// + /// + public static IDisposable BlockInvokeCallsDuringDispose() + { + return new InvokeBlocker(); + } + public override sealed void OnInvoke(MethodInterceptionArgs args) { var synchronizeObject = InvokeRequiredInfo.SynchronizeObject ?? args.Instance as ISynchronizeInvoke; @@ -61,18 +70,9 @@ beforeCall ? "skipping" : "aborted"), e); } - /// - /// Call this method with a using statement around the content of the Dispose method you want to protected. - /// - /// - public static IDisposable BlockInvokeCallsDuringDispose() - { - return new InvokeBlocker(); - } - private class InvokeBlocker : IDisposable { - private bool hasLock; + private readonly bool hasLock; public InvokeBlocker() { @@ -86,11 +86,12 @@ InvokeRequiredInfo.WaitMethod(); if (maxWaits-- <= 0) // prevent deadlocks + { return; //hasLock = false + } } - } - while (!Monitor.TryEnter(InvokeLock)); //try to grab the invoke lock (to prevent additional invokes from occuring) - + } while (!Monitor.TryEnter(InvokeLock)); //try to grab the invoke lock (to prevent additional invokes from occuring) + hasLock = true; } @@ -99,17 +100,19 @@ //give up the lock; any invokes waiting for this lock are processed after this; but if the object is //now correctly disposed, they are skipped if (hasLock) + { Monitor.Exit(InvokeLock); + } } } } //In seperate class to make sure you don't need a postsharp reference to fill in - public static class InvokeRequiredInfo + public static class InvokeRequiredInfo { + public static Action WaitMethod; //to be fill in by application: public static ISynchronizeInvoke SynchronizeObject { get; set; } - public static Action WaitMethod; // end fill in } -} +} \ No newline at end of file