Using IDisposable to control link counts

Story:

Like this question , I am looking to use IDisposable for something else besides what it was intended for.

Purpose:

The application for this is not very important, but only for a good example: I have a Windows Forms application where I implement the Undo design template. This usually happens by intercepting "Value Changed" events from user interface elements. For DataGridView , CellEndEdit , etc. However, there are cases when I programmatically change the data, and I want to do all the actions of each of them without tracking them.

Till:

I have a way to do all this, but I control my “Should I cancel” logic on the account:

 private int _undoOverrides = 0; public bool ShouldUndo { get { return _undoOverrides < 1; } } public void DoNotUndo() { ++_undoOverrides; } public void ResumeUndo() { --_undoOverrides; } 

Now this works well, but you must remember to call ResumeUndo() at the end of such business logic that starts with DoNotUndo() . And I thought:

Maybe I’m not too idiot to ruin it, but what if I had to expose this interface in the code that I miss? I would like if the compiler could take care of this for me, if possible.

Idea:

I am considering using a class that implements IDisposable for this. That way, a user of my code could use the using block and not worry about homework. This is what I still have:

 private static int _refCount = 0; public static int ReferenceCount { get { return _refCount; } } class HallPass : IDisposable { protected bool bActive; public HallPass() { ++Program._refCount; bActive = true; Console.WriteLine("Acquired hallpass!"); } public void Dispose() { if (bActive) --Program._refCount; bActive = false; Console.WriteLine("Hallpass expired!"); } } 

I have included a boolean, so I 'm sure . I am not duplicating an account on Dispose() . So, all you have to do to use HallPass :

 using (new HallPass()) { // do things... } 

Question:

Is that a good idea? Why might this be a bad idea? Any bugs I should know about?

Also, and I feel stupid for this, but I'm sure link counting is not suitable for this. This is similar to reference counting, but there is no reference to control or memory to free. Edit: It may be, it is just not right now.

It’s like a mutex or a critical section in that you are trying to throw an exception (another incorrect designation because I don’t mean what you throw ) for the rule during the code section, but it’s not either of them because they should to be mutually exclusive within the scope - this is done to be done in a nested way, if you want. That is why it is a number, not a logical one.

+7
c # idisposable
source share
1 answer

My first concern is Program._refCount , which can be accessed from multiple threads and is not synchronized. But you can claim that your application is single-threaded.

The next and biggest problem is that you are not actually using a one-time template as it is supposed to be used. I personally think that using a template in the way you use it is important, especially if you are not the only person who works on the code.

  • Instead of forgetting to call ResumeUndo() , now you need to keep in mind that you should call Dispose() . Question: Will it be natural for your team members to understand that they need to call Dispose () when they want to use HallPass ? ( using instruction is good, but cannot be used in every scenario. If there is a HallPass that lives longer than the scope of one method, you cannot wrap it in a using statement)
  • Although a bad call to Dispose() on IDisposible bad, it usually does not affect the correctness of your program - yes, your program will have performance problems, leaks, etc., but functionally it is usually still correct. However, for your HallPass , if anyone forgets to call Dispose() , I assume there will be a functional error. And the mistake is hard to track.
+2
source share

All Articles