To Dispose or Not to Dispose ?
From http://weblogs.asp.net/jarnold/archive/2004/08/10/211969.aspx
Myth:
Dispose() releases an object's memory.
Rationale:
Well, it's called 'Dispose' isn't it?
Truth:
Dispose() is merely a convenient place for a class developer to place any resource clean-up code, in the hope that clients will call it. Dispose does not free the managed memory allocated for an object. The only thing that can do that is the garbage collector; there is no way to deterministically (or manually) release memory.
Now, why should we call Dispose() for datasets and datatables and other disposable objects ?
Let's see an example:
Dim dsSomeData as Dataset
dsSomeData = objSomeObject.GetSomeData()
dsSomeData.Dispose()
dgDataGrid.DataSource = dsSomeData
dgDataGrid.DataBind()
If the Dispose() actually releases memory and marks it for disposing in the next garbage collection, this should throw an exception. But, guess what? The above code runs fine.
So, what does Dispose() for dataset and datatable actually do? Nothing! You can call the Dispose() method for the dataset, and the dataset still contains the dataset. No release of memory.
The Dispose method in DataSet exists ONLY because of side effect of inheritance-- in other words, it doesn't actually do anything useful in the finalization. The class DataSet inherits from "System.ComponentModel.MarshalByValueCompenent" which implements the IDisposable interface because it is a component. That being the case, it is only used to be treated as a component that you can put on a form. The method is not overridden in the System.Data.Dataset class and as such, it all depends what MarshalByValueCompenent does. Calling Dispose is just going to remove the DataSet from any component site that it's been added to.
This is the disassembled code of MarshalByValueComponent
Public Sub Dispose()
Me.Dispose(True)
GC.SuppressFinalize(Me)
End Sub
And the internal Me.Dispose(True) does this:
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
SyncLock Me
If ((Not Me.site Is Nothing) AndAlso (Not Me.site.Container Is Nothing)) Then
Me.site.Container.Remove(Me)
End If
If (Not Me.events Is Nothing) Then
Dim handler1 As EventHandler = _
CType(Me.events.Item(MarshalByValueComponent.EventDisposed), EventHandler)
If (handler1 Is Nothing) Then
Return
End If
handler1.Invoke(Me, EventArgs.Empty)
End If
End SyncLock
End If
End Sub
Since the DataSet does not have a container, the above code practically doesn't do anything other than telling GC not to call Finalize method. If I understand this correctly, we'll never have to call dispose method on DataSets and DataTables.
Always use dispose() if it is available
My praxis (cf Build Your Own .Net Language and Compiler) is to always expose dispose() in any object with state, and, in using any IDisposeable object, or any object that exposes dispose() (or the equivalent functionality with a different name), to use dispose() rigorously at that point in my code where I no longer need the object.
This is because great code is disciplined about the syntactical and semantic "scope" of variables, that region of text where the variable has a useful meaning. In turn, this is based on similar notions from quantificational symbolic logic in which the quantifier binds the variable.
I can't think of many situations where dispose(), insofar as it marks the object and its delegates for deletion by a modern garbage collector, would be a Bad Thing.
OK, if you create, use and dispose() a big object inside a tight loop, then it would be a Bad Thing to do this performancewise. D'oh, the best scope of the variable would be the boundaries of the loop:
objBig = New bigClass
For intIndex1 = 1 To intBig
... do something useful ...
Next intIndex1
objBig.dispose()
The above assumes that a single Big object can be reused many times through the loop. But suppose the loop "needs", or is thought to need, the creation, use and disposal of a new Big each time through.
To say "I didn't dispose() of the Big objects because it would be inefficient" is stupidity of the first water. I mean, you didn't mind creating them, did you? You don't mind them laying around until the name goes out of scope and their reference counts zero, do you?
Indeed, the dodge is one with which I am familiar: "I didn't write that code because it would be inefficient" as a lame excuse.
But far more than this, elegant computation is like a Chinese painting which restricts itself to the true essentials: the fall of waters, the sage, the thoughts of the sage.
As a prolix writer, I have heard a lot of hot air about what is necessary and what is not; I have been lectured time and again about that form of simplicity of "words" which is instead a dearth of original ideas.
This plenum of hot air includes nonsense about the "simplicity" of code which doesn't frigging bother to delete stateful objects properly.
If it's disposeable then dispose() it. Dammit.
I understand that Dispose() doesn't free memory. That's no longer the .Net programmer's job.
But in general, any object with state can at any time create delegates and recursively there is nothing to prevent these delegates from creating more delegates. The centralized garbage collector runs at a system-specifiable frequency to release the storage associated with these delegates, but if their parent object hasn't decremented their reference count by setting its reference to nothing, then the garbage collector THINKS it needs to leave the object alone.
Unlike a real garbage man, the garbage collector sees the used Vaio computer or Sony Triniton sitting on top of de can with a label that says n references where n>0, and he says, boys, leave it alone. No homeless person comes by to grab the loot, unlike last June in Shenzen. I put out, without guilt, an old Presario to the trash...knowing that what did happen, would happen: within minutes, invisible hands had spirited the thing away to a useful life in Zhong Guo, and I didn't have to figure out how to drag it, with all my other stuff, in Lo Wu.
But, I digress.
The system slows to a crawl as less and less storage is available for useful work as opposed to misplaced reverence on the part of the garbage collector for dreck.
What's worse, the crisis is unpredictable over the system lifecycle because at one moment in that lifecycle, the nondisposed object has no reference objects, but, later on, its developer decides it needs one or more reference-delegates (as opposed, that is, to simple "value objects" such as numbers, or strings, which occupy a modicum of space and cannot delegate).
No user object (as opposed to a string) is ever prevented over its useful life from instantiating a delegate.
Oops, system slows to a crawl. Worse, nobody is actually responsible, everybunny has done his job...except for adhering religiously to my favorite rule, dispose() if you can and when you are finished.
Dammit.
A near isomorph of ecological disaster is created. Each developer is concerned only with his own code, wants to "save time" by not typing the dispose() command, and thereby "externalizes" costs...not, as in the case of the physical environment, by throwing out useful goods, but, in the .Net environment, NOT throwing out useless "goods".
Like the closets full of perfectly useful clothes found in *haute* bourgeois homes in America, not donated to Oxfam or the United Nations High Commission for Refugees so that Palestinian kids can sport Louis Vuitton labels in refugee camps, the waste is invisible but real.
There are, in fine, a set of practises in the small which started years ago with structured programming and which, IMO (it ain't humble) include constant respect-for a minimal object state.
That is: your needed state (the actual collection of actual variables actually needed to solve the problem) should never diverge from your "concrete" state (the actual collection of variables at time t in your program including active reference to reference variables).
The Cobol psychology was to keep a lot of unnecessary variables in Common storage and to treat them with Eleusinian respect. The resulting code was bloated with superstition and as a result almost impossible to maintain.
.Net does spread the illusion that the programmer is no longer responsible for variable scope because in the folklore, round de campfire, young and nubile programmers are advised by grizzled Elders that they can no longer "delete objects", and the wisdom, in the folkloric world of MIS, is received with such awe, such reverence, that somehow I am certain (based on my experience with parallel situations) that many young and nubile programmers are admonished for even using dispose()...as if the use was *prima facie* evidence of their ignorance of the Eleusinian mysteries.
But despite the fact that storage management is centralized, and despite the fact that this is Good, the programmer still remains obliged to know what is in scope and what is not. It's not a matter of folk-lore, folks. It's a matter of science, and scientific elegance.
Dammit.
Re:Always use dispose() if it is available
I agree that dispose must be called if it is available. But, it depends on where it is available/implemented. As a general rule, I would say that, call dispose if the class of the object implements IDisposable or overrides the Dispose method in it's parent class.
If the dispose doesn't do anything; why call it ?
Over-disposed
If you are done using an object, why not just set it to null? Calling does nothing unless you are releasing unmanaged resources; the only other thing you can do is set internal references to null. But this does not immediately release any managed memory, it only removes the reference so that the GC can collect it later (assuming there is no other reference to the object hanging around; and if there is another reference, you shouldnt be disposing the object because that other reference might still be used). Setting the reference to null also removes all references, allowing the GC to collect them when it chooses to. The theory behind Dispose was always to release unmanaged resources, because the runtime couldnt know how to release them itself. Implementing Dispose on all "stateful objects" is overkill and, yes, inefficient.
I disagree
It's not at all my understanding that dispose is only necessary for unmanaged "resources". For each heap object other than the string, you need to decrement its reference count (by setting its ref to null), otherwise the .Net heap gets cluttered and slows performance globally.
Furthermore, implementing dispose for stateful objects provides a clear place to implement disposal of resources that object may acquire in future editions.
Suppose an object is written which in fact creates no new heap objects except strings (a special case). It doesn't implement dispose().
Then, various other objects start calling on the new object and don't dispose it: only set it to null.
Then suppose the new object is enhanced ... to create objects that use heap space.
Each prior use now creates heap clutter that the garbage collector doesn't see. You have to go back and you have to change each prior use to implement dispose!
Because programs CHANGE, I conclude that any nonstatic object should implement if necessary a null dispose() that being null does nothing.
Furthermore, dispose() is an excellent way in code to delineate the "scope" of a particular object. All objects should use the fact that in .Net languages, they get storage in the block, not at the beginning of the enclosing procedure, and dispose further narrows the scope, making the code more readable.
As to "overkill" there's NO SUCH THING in a context where most software has bugs, some of them hidden as in the above example. IMO.
"Unmanaged storage" has as far as I know nothing to do with the issue. "Unmanaged storage" appears to have become a vague signifier for a zone of excuses, a zone where at one and the same time, the rules don't apply, and, paradoxically, you have to follow strange rules.
No, you should set MANAGED objects as you say to null. The problem is that if the MANAGED object had created 1 or more MANAGED objects on the heap, these objects still exist, as far as I know.
Middle Ground for Dispose()
My final two cents on this topic:
As I understand it, the intent on the part of the .NET designers re: the IDisposable interface and the Dispose method is to provide an explicit, if imperfect, mechanism to compensate for the primary downside of asynchronous garbage collection and non-deterministic finalization.
Calling the Dispose() method on any object communicates *nothing* to the .NET runtime. It does not decrement the reference count, it does not speed up garbage collection, it does not cause the runtime to decrement reference counts on class members, and it does not assist in keeping the heap efficient. The Dispose() method is purely intended for use by a class designer to use as he or she sees fit to clean up resources. The only code that executes when Dispose() is called is custom code implemented by the designer of that class.
The *primary* intent of Dispose() is to allow a class to clean up, to quote Don Box, "scarce resources." It's a compensating mechanism in the .NET framework for the downsides of asynchronous garbage collection and non-deterministic finalization--downsides, it's important to note, that only come up in certain unique circumstances (such as a with a class whose lifetime corresponds to an open file handle or database connection--"unmanaged" resources).
However, the use of Dispose() is not limited to the purpose of resource cleanup because when it comes down to it each class designer is free to take whatever actions he or she sees fit when Dispose() is called. For example, I found one example in the Anders Hejlsberg's book The C# Programming Language describing how enumerator objects in C# use Dispose(): they use it to "reset" the internal state of the object. It does not, as far as I can tell, clean up any resources. It's purely used for state management inside the class.
So if non-resource-cleanup usage for Dispose() is good enough for Anders Hejlsberg, the designer of the C# language, it's good enough for me. Each class designer can make his or her own choice of whether to use Dispose() and what to use it for.
As I understand it, the implementation of IDisposable by a class is a *signal* (at the level of human communication) to the user of a class that the designer of this class has made a decision to do something important with the Dispose() method. In my opinion, it is therefore good practice to call the Dispose() method on any object that implements IDisposable(). It is the proper response to the "signal" sent by the class designer who elected to implement IDisposable.
It if for this reason, Edward, that I disagree with your assertion that all stateful objects should implement IDisposable. If everyone implements it all the time, then it's somewhat analagous to a "crying wolf" situation in which the objects that really *do* need resource cleanup are ignored because the meaning of IDisposable has been diluted by the fact that every object is sending the signal "I need cleaning up!". The signal becomes noise. I 100% empathize with your desire, Edward, to program defensively for future class changes that might evolve into requiring cleanup, but I also suspect that your attraction to this technique is based on your idea that Dispose() somehow aids the runtime with resource management--and I just don't think that's the case.
I also think, though, that because of this imperfect situation it is best of class designers find ways to solve design problems *without* implementing IDisposable. Given the situation the .NET designers have handed us with asynchronous garbage collection and non-deterministic finalization, and given the nature of this imperfect tool we have (IDisposable), the best thing class designers can do is to reserve IDisposable for exceptional circumstances. I believe that avoiding class designs that require deterministic cleanup is the best way to manage macro-level risk of resource leaks creeping into systems.
Dan
Unmanageable Disposition
No, you should set MANAGED objects as you say to null. The problem is that if the MANAGED object had created 1 or more MANAGED objects on the heap, these objects still exist, as far as I know.
This is incorrect. Garbage collection in .NET does not use reference counting per se; it uses what is called reference tracing, where the garbage collector determines in a real-time fashion whether there are any references to an object that can still be accessed from running code. This has two advantages over reference counting: it keeps you from having to explicitly set a reference variable to null, and it eliminates the problem of circular references. Once all references to a particular object have been released, all references contained by that object are also implicitly released, because they can no longer be accessed. Thus the garbage collector DOES know that they are available for reclamation, and you dont have to implement IDisposable to make that happen. THE POINT: calling Dispose by itself DOES NOT release managed memory, because you still have to wait for the garbage collector to run. This is in effect no different from setting the reference to null (unless there are other references to the object, in which case it is usually a bad idea to Dispose of the object anyway).
Again, this is only true for managed resources; the run-time does not have the ability to release unmanaged resources even if it knows that the managed pointers or handles to those resources have gone out of scope. That is the purpose of IDisposable; to allow the class to clean up those resources IN A TIMELY FASHION. Of course this could be done in a finalizer, but this has two problems. First finalizing in .NET is an "expensive operation", and second, you never know when it is going to happen. This is usually ok for managed memory, because the .NET run-time is managing the .NET heap. But because unmanaged resources are usually system-level resources (such as file handles and device contexts), they are usually limited, therefore their release is more time-sensitive. So Dispose gives you a way to release these objects without waiting for the garbage collector to run the finalizer. Of course you could do this without implementing IDisposable; you could do it however you choose. IDisposable is merely the Microsoft recommended way of doing it, and the way that provides the most benefit as far as integrating with .NET languages (e.g. the C# using keyword).
And there is nothing vague about unmanaged resources, if you actually understand the concept of the CLR and its memory management scheme. While .NET does its best to remove memory managements from the purview of the developer and make it the resposibility of the CLR, there are some cases, usually involving system-level resources like file handles and device contexts, where this is simply not possible. Developers must be aware of these cases and handle them approriately, by, for example, implementing IDisposable where appropriate.
.NET Reference Tracing
Garbage collection in .NET does not use reference counting per se; it uses what is called reference tracing, where the garbage collector determines in a real-time fashion whether there are any references to an object that can still be accessed from running code.
That is interesting information. Thanks.
Dan
Nope, always use dispose
You'll get a compiler error if the object doesn't expose it unless you aren't using Option Strict in VB, and you should always use Option Strict.
If the object doesn't expose a dispose() you need to ask yourself if it is any good. Many Microsoft objects don't. Well, are they any good?
The persistence of myth
The original poster to this thread was concerned with showing a myth (that dispose() releases memory) was false and this was a laudable aim.
However, my reading of Barthes and my DP experience has shown me that myths are "sticky" and it is hard to escape from them.
The neomyth is that one not need dispose() because of the paleomyth, but IMO it becomes even more important to use it,
IDispose All the Time?
Hi Edward,
I'm not sure I'm aligned with your absolute stance on Dispose(). When you write:
"If the object doesn't expose a dispose() you need to ask yourself if it is any good. Many Microsoft objects don't. Well, are they any good?"
Are you arguing that *all* classes should implement IDisposable?
Dan
All stateful classes
If the class has any state in the form of values that persist between procedure invocations then it should implement dispose(), in my view. This should be the case even if the object state consists of value objects and strings, because the object should be free to create reference objects over its system lifecycle.
I use this rule in Build Your Own because of the danger that a stateful class might be changed to create a reference object sometime in the system lifecycle.
However, stateless classes should NOT have dispose(), a fact that exhibits their statelessness.
I concede that over the system lifecycle, a stateless class might get state but my experience is that this seldom happens, and, it indicates a serious design flaw.
Thanks for the interesting tech info
but my concern is to program independent of the specific methods used in Framework. As it happens, I implement a dispose() in my book without using IDisposeable in some cases which from a standpoint of communication-of-intent is probably bad practice.
One of my primary purposes in dispose() is in fact to have the object inspect its final state for correctness. Other ceremonies can be conducted at dispose() time. For example, the object could log its termination in an appropriate place.
In my C praxis I can "see" that malloc and free must always balance and I am writing the utility to match malloc and free messages. I would think that having dispose in addition to constructors would allow one to add audit code to a system for a similar reckoning whose negative result would be an apriori indication that the system needs further work.
There's no need as far as I can see to set reference objects to null in dispose because when they go out of scope, the reference tracer (not the reference counter) knows they no longer exist. As David points out the algorithm used means that setting them to null is useless although IMO "inefficient" only in the *de minimis* sense of micro-efficiency which wastes a lot of programmer time.
However, even if a reference counter were used the "ideal" framework would not need application code to set anything to null, because it would know when the object goes out of scope.
[I suggest a style of coding that given the fact that Microsoft can change the Framework, reasons about a minimal, ideal Framework so as to stay within a margin of safety, in the way in which Chinese people living under Chinese law implement a margin of extra caution in their daily lives so as to stay out of trouble. This may offend computing libertarians, but I like working code.]
I'll be the first to admit it. I am being deliberately obtuse and refusing to "stay current" with the details of the implementation of the underlying system because it's been my experience that code written by a programmer who is TOO *au fait* and groovy-with-respect-to the operating system contains mental hooks to implementation details.
Furthermore, hard scope is important to reliability. An object should exist when it exists and should "leave not a rack behind" (through an explicit dispose()) when it dies.
This is even more important in multithread applications which in my experience require the object to clearly define when it is being-born and busy-dyin':
For he who is not busy bein' born is busy dyin'
- Bob Dylan, It's All Right Ma, I'm Only Bleeding
There needs to be bright lines in the form of object semaphores (available in crude form in .Net via Interlocked) at the moment of conception and the moment when the object startup is complete, and at the moment (signalled by dispose()) when death begins and when the object completes its last rattle and thrash.
But if the object does not implement my pro forma dispose() in version 1.0 then it becomes, when the time is ripe (die Zeit ist hier) to multithread, just harder to find the time at which to add the code. Whereas a dispose() can be wrapped in a synclock which prevents incoming requests from starting up.
Having seen the consequences over thirty years of smart people meditating on and committing to memory the MISTAKES made by OS developers, and as treating those mistakes as Holy Writ, I would rather ponder code that is truly efficient where you aren't efficient until it works.
Ponder the difference between a monstrous system with no clear dispose(), littered with objects on life support, and a decent and condign burial for each object at the end of its useful life. Aesthetic considerations, as Dijkstra knew, are often ethics and mathematics in a tutu and as such must be taken seriously.
However, I want my code to be fully independent of the technology (reference tracing, reference tracking, or Ouiji boards) used in the operating system, and I am willing to sacrifice micro "effiency" to do so.
I think it was a mistake to implement asynch garbage collection in this way which makes it possible for individual application programs to barf the system. But I don't know if I could have done better.
This is one of the reasons that I am leaving .Net development because it seems that in each commercial closed system I have encountered there are these "features" which offload the need for thought onto the users, who then are tasked with remedying the defects of the operating system.
Sour grapes? Perhaps. But we make fine wine from sour grapes, as well as swill.
And I appreciate Donna's kind remarks. They are probably undeserved since I have smoked a lot of computing equipment in my day (metaphorically) in addition to smoking other substances literally. But it seems to me that reliable and safe computing is more ecofriendly and results in fewer trips to the Gizmo Shop.
Sounds like your old man, Donna, is a man of parts (many parts, all in the garage). You shall be rewarded when those computing classics become valuable museum pieces. My many moves, sadly, have caused me to abandon old computers to their fate, but in recent years I have done so carefully.
For example, I was looking at manually humping all my worldly goods out of Red China last summer therefore I put a Presario in the trash, but I knew that it would be immediately useful, and five minutes after I put this orphan out, it had been spirited away. It was fully loaded with VB Enterprise and other goodies so it's probably serving the world struggle of the intelligentsia forces of the aroused proletariat against the running dogs of the Fascist capitalist imperialists.
Or, burning illegal DVDs.
Had I been in the USA, I would have given the damn thing to a church, a synagogue, a mosque, a Hindu *ashram*, a troop of Girl Scouts, or the Socialist Workers Party.
I Don't Have the Luxury of Full Independence from Technology
However, I want my code to be fully independent of the technology (reference tracing, reference tracking, or Ouiji boards) used in the operating system, and I am willing to sacrifice micro "effiency" to do so.
As it appears you have yourself concluded, I think Windows .NET development is simply not for you. I'm not arguing that .NET and Windows as it is today represent the best possible situation, but this is the platform in use by the people who pay my salary, and the clients that purchase the services of our company to develop software for them that will add value to their business.
My point of view as a craftsperson and tradesperson for hire is that I am bound to do my best to work within the capabilities of the tools and platform in which I am being paid to work. I have to balance technical goals against the interests of my client and employer, both of whom are driven of course by business-oriented concerns. Discussions of an ideal system are interesting to me, but ultimately hypothetical. In your position, Edward, I say idealize away, but I suspect the road you are seeking is outside the Microsoft world, as you have yourself alluded to in your recent post about switching from .NET to C development. If I were myself working towards different ends in my daily technical work, I might join you.
Dan
Here I am havering about the "persistence of myth":
but my own recommendation is a mythos too.
Oops. My only defense is that some myths are better than other myths and that myths that overdo "effiency" myth the point which is reliability before wrong answers at high speed.
Man is born free but everywhere in chains, Dan
No, I think my rule applies even in MIS .Net development, Dan. In fact it applies even more because other people will depend on your code continuing to work for all of its client objects after change.
The argument here has the structure of one advanced by Kant after he put forward his ideas for universal peace and harmony, as was met with the "practical" objection that "this is all very well in theory but won't work in the real world".
Kant replied that he was concerned with the real world and meant his recommendations for universal peace, based on trade and democracy not as ideals but as a practical solution to the real problems of a Europe, that had undergone a global war in the form of the Seven Year's war.
I would use dispose() in a business .Net application precisely because doing it correctly in MIS is far more important than doing it correctly in hobbyist programming and arguably more important than in scientific programming where users are on average better positioned to take computer results with a grain of salt. Furthermore, microefficiency is often not important in common business applications, and microefficiency gains are not nearly as important as choosing algorithms with low polynomial time.
As it happens, because this rule isn't followed, people get screwed, as far as I can see, many times in their relationship as consumers and employees with businesses. Credit "black marks" made by erroneous software (perhaps because an object was never disposed) turn out to be not erasable because the software to erase them isn't ready yet and not considered critical because the real user is the bum who probably has bad credit anyway.
Veterans beg for health care that they were promised when they returned from Vietnam and are told to fill out THE SAME FORM repeatedly because despite all the "efficiency" of MUMPS, it can't properly network as can Oracle.
In fact, it is a well-known scandal in American health care that owing at base to the unavailability of software that keeps working after its text has been changed (the goal of my dispose() rule!), no one patient record exists, and instead information has to be entered and re-entered repeatedly to qualify for what should be a human right. During my Father's illness, I had to repeatedly meet with clerks who although they had computers continually prompted me for the same set of information and his care was screwed up because not all computers had the same set of medical facts.
This stems in part from the fact that all the way down, software isn't trust-worthy. We cannot know that it hasn't been changed, for example, so that it allocates a resource today which it did not allocate yesterday in such a matter that its unwitting clients use the software object, today UNWITTINGLY allocating those resources such that starting today, the use of the clients (which haven't been changed!) causes the system to slow down.
Therefore and as a result, it appears that reinvention is the norm in health care and patient records are incomplete and incorrect. The real user, the patient, pays the cost.
New systems are carefully designed as "object oriented" and then PROGRAMMED as static functions in the "OO" language which (whew) allows the programmer to avoid having to program objects. Or he then learns enough to be dangerous...and starts creating objects. But he is told it is "overkill" to worry about destroying them. He is laughed at not for his bugs but for "unnecessary" code which violates a nano form of efficiency by programmers who can't discern common errors in their own code and who triumphantly discovered the incorrect way to perform a binary search last week.
Computing personnel are continually in this culture urged to forget their integrity and not insist too loudly in code reviews on a practice they think or know will ensure the long-term reliability, not of a specific piece of code, but of the family of related programs that is changed over time to meet changing needs.
Indeed, in my experience, their loud insistence becomes in the data processing pop culture an unpleasant personality quirk and they find themselves sent to various corporate re-education camps...some of them operated by Jerry Weinberg...in which the TECHNICAL problem (that code really does exist not as specific bit patterns but as families of related solutions, including solutions that at first do not allocate reference objects) is recoded for corporate convenience as some sort of a personality problem.
Now, because I have educational experience including service as an instructor or adjunct prof at three universities, and because I have escaped America, I am able to escape this problem set which in my experience is unsolvable, because in my experience in the USA programmers are regarded as a lower form of life who are not entitled to have "professional" views in any enforceable sense.
But I have to say, Dan, that I am very, very offended by any phrasing which in any way implies that I am not "qualified" to do .Net programming because I won't change the view to one in which I don't dispose(). I am offended because you are asking me once again, as has been asked before, that I essentially live a real contradiction.
On the one hand, I am supposed to show up as a professional for a .Net job and do the best job possible helping to create large and critical systems which have to be correct first and then efficient.
On the other, I can't make a discovery or form an opinion at variance with the local practice of the team. Unfortunately, because of the depth of my experience, you can bet your sweet patootie this is what I'll do. I may be wrong and my practice may suck, but the past experience will be unavoidable, and I'll find it impossible to take a stupid pill (or drink from the waters of Nepenthe) in order to be a sunny corporate drone. I'll also find it a bad deal, financially, as every day, things like health insurance and affordable living space disappears.
I was listening the other day to some recent ragas composed and played by Ravi Shankar with his daughter Anoushka. What I like about Indian music is that it deconstructs the bound between song and speech, and its rythym is not externally imposed but imposed by the original direction of the Vedic hymn on which the raga was based.
The only thing worth doing is one in which you are this type of *pandit* who subordinates himself only to the demands of the work of art. If you cannot be a *pandit* then be a *guru* and teach. I may suck as a *guru*, of course, but I am at peace with myself.
I continue to believe that in a just and open society (such as the labor-friendly university in which I started programming) the first computing concern would be with truth (requirements are matched by the code over time and change) and only then with an "efficiency" which on the ground means "we don't have time for certain types of people...certain scheduled castes...certain transactions...and certain considerations".
This isn't computing. It's police work which uses the discourse of "efficiency" to make the ATM user, who has only 100.00 in his bank account, feel small and indeed unscheduled when the ATM informs him that 100 is not divisible by 20.
My recommendation for programmers who find themselves working in a frustrating corporate environment is very simple:
The problem is all inside your head
She said to me
The answer is easy if you
Take it logically
I’d like to help you in your struggle
To be free
There must be fifty ways
To leave your lover [employer]
She said it’s really not my habit
To intrude
Furthermore, I hope my meaning
Won’t be lost or misconstrued
But I’ll repeat myself
At the risk of being crude
There must be fifty ways
To leave your lover [employer]
Fifty ways to leave your lover
CHORUS:
You just slip out the back, Jack
Make a new plan, Stan
You don’t need to be coy, Roy
Just get yourself free
Hop on the bus, Gus
You don’t need to discuss much
Just drop off the key, Lee
And get yourself free
She said it grieves me so
To see you in such pain
I wish there was something I could do
To make you smile again
I said I appreciate that
And would you please explain
About the fifty ways
She said why don’t we both
Just sleep on it tonight
And I believe in the morning
You’ll begin to see the light
And then she kissed me
And I realized she probably was right
There must be fifty ways
To leave your lover (or the boss)
Fifty ways to leave your lover (or the boss)
CHORUS
I hope that this blog entry doesn't damage our long-distance friendship or get my ass fired from developer dot star. It's not as if I need the money but I like youse guys.
Agree to Disagree
Edward wrote:
No, I think my rule applies even in MIS .Net development, Dan. In fact it applies even more because other people will depend on your code continuing to work for all of its client objects after change.
I think we'll just have to agree to disagree on this one, Edward. I probably did not explain myself well enough previously. When I wrote this:
My point of view as a craftsperson and tradesperson for hire is that I am bound to do my best to work within the capabilities of the tools and platform in which I am being paid to work. I have to balance technical goals against the interests of my client and employer, both of whom are driven of course by business-oriented concerns. Discussions of an ideal system are interesting to me, but ultimately hypothetical.
What I meant was that, in my opinion, the best way for me to serve the people paying for my services, and at the same time the best way for me to create systems that will be recognizable and understandable by future maintainers, is for me to follow the conventions of the platform. The conventions of the platform, as established by the platform vendor and as generally agreed upon by the community, is that IDisposable and Dispose() are intended for use as I described in a previous comment. If I truly thought that there was something incorrect about the suggested uses for IDisposable and Dispose(), then I would take a different position, but I am satisfied with this suggested solution to the downsides of non-deterministic finalization.
You also wrote:
would use dispose() in a business .Net application precisely because doing it correctly in MIS is far more important than doing it correctly in hobbyist programming and arguably more important than in scientific programming...
Here again, we'll have to agree to disagree, because I disagree that what you describe is "doing it correctly." If you want to code your libraries to always implement IDisposable, then that is your perogative, and were I coding against your library I would do my best to match your intent and call Dispose() when finished with one of your objects. That is keeping to the spirit of the intent of IDisposable: respecting the class designer's desire to have deterministic finalization. But I will still contend that implementing IDisposable on every class is overkill and dilutes the usefullness and original intent of IDisposable.
Changing subjects a bit, please don't mistake me as someone who is frustrated working in the corporate environment. I am not. It's not a perfect world, but I am satisfied. The bottom line for me is that I perform work for hire. For me to take the money from my employers and clients and then to fight against their interests in the process would make me feel hypocritical (some amount of hypocrisy and contradiction in life is inevitable anyway). There are certain kinds of companies I won't work for, and certain kinds of projects I would prefer to avoid, but I work for money. I do my best to work within the bounds of professional ethics and my own high standards for quality, correctness, and sound workmanship, but beyond that the interests I am serving are my employer's and my clients'. If I don't want to serve their interests, then I should stop taking their money. I may reach that point someday, who knows.
Finally, I must come to the defense of Jerry Weinberg. It is supremely unfair, not to mention incorrect, to describe Jerry's workshops as "corporate re-education camps."
Best,
Dan
dispose(), not IDisposeable
I don't implement IDisposeable but I do always code a dispose() with the intent that it be used at the instant the class is no longer needed. My versions of dispose() always set a Boolean flag in the state to False, and each method and property (including dispose()) tests this flag before doing anything.
If the Boolean flag, always called blnUsable or booUsable, is False, the property or method will return a suitable default value if it has a nonvoid return and throw an error.
The constructor sets this flag to True on object startup after it is certain that it has required all needed resources. The flag may be set to False by any non-static procedure when that procedure detects corrupt data or a programming error (such as a case statement without the expected list of values).
This practice, Dan, is like that of the White Knight in Alice in Wonderland: "it's my own invention".
I totally agree that in a work for hire situation, Job One is most of the time to get along technically with the team. This rule applies even if the "team" is the 1919 Black Sox, that Chicago baseball club that deliberately lost the world series so that Meyer Lansky could make money.
The problem for me is that in my experience, the Black Sox teams have increased in number.
I am not claiming that most or even many corporations are engaged in fraud on the scale of the Black Sox (although we did learn that Enron, formerly well-regarded with a large and progressive MIS department, was). But I do claim that the players in many organizations are under subtle Black Sox pressure to not play baseball but to serve a self-defined unique "customer" who is merely the most powerful player in a corporation...that remains, despite the spin, a collection of individuals who are competing with each other.
Given that this is my view, it's my responsibility not to work in MIS, because my code would look so dissimilar to that of most .Net developers. There is a genuine need for code to look alike just as I learned when I studied engineering drawing that the boss wanted my drawings to look like those of every other competent draftsman.
This has been an old problem of mine. A computer operator in 1972 who was looking at one of my printouts and who was studying assembler for the mainframe refused to believe that my code was BAL. Every line had a comment and the identifiers were mostly at the maximum size.
But the initial wrong remains in an American MIS culture that so unquestioningly supports private needs and refuses programmers the ability to generate a true professional codex. Draftsmen could aspire to be registered professional engineers, but today, no such career path exists for programmers, only a vast wasteland of management or being a Microsoft MVP, where despite the fact that great people are MVPs, you simply have to be loyal to Microsoft's directions.
Offshoring has further put paid to the very idea of programming professionalism, although I support offshoring for other reasons including global fairness.
As to Jerry Weinberg, he is a good person I am sure. But he is ALSO responsible for the way "structured programming" was used to humiliate good programmers by the time "structured" came to mean in 1980 "I, who are stupid, can understand it".
Fifty ways to leave your lover
Note: I post *pro bono* and am not paid. I regret if my final sentence implied any other relationship of business or employment. I am a volunteer at this site.
But I am no longer even qualified in the technical sense to post on .Net because I can't afford to stay current. At the same time, I reject any imputation that my bad attitude is the problem. It's a straight technical problem.
Therefore I shall post on Open Source and on C for the most part while developing my own language. Long term I plan to acquire a Linux-only development system. I hope this meets the needs of users at this site.
Weinberg
I loved The Psychology of Computer Programming, Dan, but it was like Elvis' 1959 Heartbreak Hotel: you wanted the song to tell you more about what life is like "down at the end of Lonely street" but economic forces (the limit to the song imposed by the then-popular 45 RPM recording format) and a mental ban on "negative thinking" combined as a constellation (two remote things which act together in social phenomena) to force Elvis to sing more upbeat songs: the theme in HH was taken up by Coltrane.
Likewise Jerry had bills to pay (the American phrase MEANS economic, and partly deterministic, economic forces which in Europe would have different names) and having been fired by IBM (a difficult stunt before Lou Gerstner, who made it easy) Jerry was forced to make structured programming, structured design, and the psychological mindset of humility, openness and transparency (a mindset IMO at war with the competitive anger that constitutes a successful mindset in laissez-faire) into saleable, marketable commodities.
He had to "sell" his classes first in the structured design techniques and then in a more general team-building as classes that would increase productivity. He could not say that programmers would be happier and that would be a good thing.
In a different society, he might become part of an NGO organization funded at strictly apportioned proportions by government and corporations with the mission of creating and maintaining a highly professional programming work-force.
To the extent, mathematically defined, he received tax dollars he COULD talk about human flourishing and human happiness as goods in themselves logically independent of productivity. Hell, if he's spending my tax money, he'd better talk in some measure about MY personal pursuit of happiness.
But as it is, in seminars where the bottom line rules, we have to be at all times ready to reword such fine phrases as "human happiness" in such a way that they do not occur in texts which instead state that the corporation's profits will increase, and hell, won't THAT be great.
This is as reductionist in its own way as vulgar Marxism and it results in a constant low-lying tension in MIS. Basically, I have been told more than once that I am not supposed to have fun at work even though I have strange ideas of what is fun inclusive of good code and my little dispose().
Work "for hire", I agree, is in America a demand that you always be ready to obey the boss or leave if you can't abide by the rules. Indeed, this is the case in Hong Kong...MORE so than in America. I have to punch a timeclock (something I like doing because it starts and ends the work day clearly) even though I am a "professional" as a teacher.
But note that in America there are additional shackles created by a more generalized laissez - faire. For example, American programmers live I think in fear of unexpected medical costs.
By labeling Gerry's classes re-education I didn't mean that they are all bad. SOME Chinese "re-education" is good, for example, the treatment of first time drug offenders in China emphasises recovery from addiction while in America imprisoned addicts often are also denied the ability to get treatment or attend meetings.
But basically, in any corporate humanism, the corporation's needs will be first and foremost in a society in which the public sector has resigned from its role as helping people out in the main.
Corporate humanism just like Leninism always allows the system to victimize people invisibly and at the crisis. The only REAL humanism is, well, humanism, and as I read Bernard Henri Levy's book Sartre, I am hoping to confirm that even Sartre learned this.
Paul Simon
I should add that in the view of my Yi Number One Son, Paul Simon is a total baby Boom sell-out who writes anthems that justify desertion and abandonment. And it is true that Simon's songs can at times exhibit precisely that sort of maudlin and emotionally self-indulgent quality one hears at times in the haverings of a Steve Jobs or any member of the Live Aid rock royalty.
Nobunny is perfect. Especially not me.
(Oh no, not Leonard Cohen! Not Bird on a Wire!)
OK, enough. I gotta start listening to music again. I think I will go out and buy my third copy of Gracelands.
[No, I can't afford an iPod].
"The dead Father was killing the musicians" - Donald Barthelme
Dispose || !Dispose
I just read the comments posted by Edward G Nilges. I must say, while I found it to be very interesting reading, it was entirely devoid of useful information. OK, so I'm not a grizzled guru of coding. That's how I got here in the 1st place, looking for useful information.
Each time I go hunting for an answer to some particularly vexxing problem, I find more of this sort of self indulgent ranting than I do answers, (yeah, yeah, I know, I'm doing the same right now) most of it not nearly as entertaining. Perhaps, if I use "-IMO" and "-IMHO" in my search string, I'll find less of this.
my $.02
back to my quest.
No answers? Really? So sorry...but...
The "answer" was that you can clutter the heap without meaning to if you set a reference to null, and the referenced object contains references, EITHER in its current incarnation, or in a new version: the answer was informed by a vision of software as it exists in reality, in which a software artifact BY DEFAULT is a set of artifacts under continuous modification IN REALITY.
Now this is just about as simple as I can responsibly make it.
Sorry I was verbose, but I am in the process of thinking through a process, that of programming, in which the programmer is made too often into an object not permitted to think outside the box. My goal is to use language to show that the best programming occurs in full awareness, not in a narrow technical FAQ awareness, in which we're all rushing to get a job done and making a lot of mistakes.
IDisposable design pattern for .NET 2.0??
Hello,
I was wondering about an implementation of the IDisposable design pattern that would work in .NET 2.0 (or 3.0) where by the interface is implemented in a base class and the derived classes do not have to implement the interface.
I found an article on the web and it works great for .NET 1.1 but in VS2005 with Code Anal-ysis turned on, it does not work.
http://www.vbinfozine.com/a_disposable.shtml
Anyone have any ideas?
dispose
I'm going nuts myself because I do indeed put in the equivalent of an isDisposed flag in each class. I've generalized it and its name is always booUsable (yeah, I am a Magyar and I like Hungarian).
It has a more general use than MERELY indicating that the class instance is disposed. It also can show that the class has performed an internal self - inspection and found serious assert failures, the sign of a software bug (yes, code can and should know it has a bug).
However, I end up, in Build Your Own .Net Language and Compiler and more recent .Net code, with a repetitious infrastructure, and this while not NECESSARILY bad is a sign of trouble.
I grow weary of implementing my usability infrastructure, and this is the weariness of the artist who wants to create something new. This echo of an outdated bourgeois sensitivity has to be taken seriously because technology necessarily embeds the bourgeois sensibility.
The answer is in my language spinoza, which I am working on. Basically, .Net did not fully factor, as did Eiffel, the distinction between a class and an object, but even Eiffel does not "understand" the common needs of all classes on earth...their "human rights".
Basically, if a class has state, it needs to know when it is "disposed" or "not Usable" and it needs in this state to go on strike.
Lemme look further at your stuff and get back at you.
Interface implementation is the wrong answer to a need that is only met by MULTIPLE INHERITANCE. This is because there is no apriori reason why the thin interface may not grow over software evolution to something fat with state.
I realize that it is the fashion to be lean, mean and stateless. However, this becomes managerial anti-intellectualism in which the use of memory becomes thoughtcrime, and this is bullshit.
This article was really
This article was really helpful. Thanks Bijesh Kuruvar for the good info.


Dataset Dispose
That's a nice bit of sleuthing there, Bijesh. Sherlock Holmes would be proud.
I wonder whether the .NET documentation explicitly states that Dispose() should be called for Dataset...or is the expectation to call Dispose() implicit in the fact that IDisposable has been implemented by the class designer?
If IDisposable has been implemented, are we better off (that is, safer) in the long run simply trusting the class designer and calling Dispose(), even if, as in a case like this, we're pretty sure it's a useless call?
Dan