473,396 Members | 2,018 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

C# and destructors

Hi,

lets say that i have class (C#) which will create some kind of communication
chanel, which is very expensive in terms of computer resources, and
therefore should be closed, when no longer needed. I have a method which
will create this chanel and a method which will close/release it.

My question is: is there a place where i can release this chanel if user
donīt call my release method? Can i write something like this:

public class MyClass {
// My communication chanel
private TheChannel m_Channel;

public MyClass() {
m_Channel = null;
}

~MyClass() {
if( m_Channel != null ) {
// Release channel
}
}

public void CreateChannel() { //... }
public void CloseChannel() { //... }
}

This method seems to work! But documentation says that "C# has no
destructor." It also says that is should use Dispose-method, like all the
..NET classes do, but it doesn't work!
Kimmo Laine
Nov 16 '05 #1
10 3264
Hi,

Please refer to the MSDN library on implementing the IDisposable interface
in components and the related design pattern.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://www.x-unity.net/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Kimmo Laine" <reply.to@newsgroup> wrote in message
news:uk**************@TK2MSFTNGP09.phx.gbl...
Hi,

lets say that i have class (C#) which will create some kind of communication chanel, which is very expensive in terms of computer resources, and
therefore should be closed, when no longer needed. I have a method which
will create this chanel and a method which will close/release it.

My question is: is there a place where i can release this chanel if user
donīt call my release method? Can i write something like this:

public class MyClass {
// My communication chanel
private TheChannel m_Channel;

public MyClass() {
m_Channel = null;
}

~MyClass() {
if( m_Channel != null ) {
// Release channel
}
}

public void CreateChannel() { //... }
public void CloseChannel() { //... }
}

This method seems to work! But documentation says that "C# has no
destructor." It also says that is should use Dispose-method, like all the
.NET classes do, but it doesn't work!
Kimmo Laine


Nov 16 '05 #2
not quite true (not sure where you read that). C# has both a constructor and
destructer, and you have implemented the latter in your code.
Some classes already inherit and implement the IDisposible interface.
Otherwise the class must inherit it to allow you to make available and
implement the Dispose method. So in your code you would need...
public class MyClass: IDisposible
{..
Dispose()
{
//implementation here (clean up)
..
}
}

--

--

Br,
Mark Broadbent
mcdba , mcse+i
=============
"Kimmo Laine" <reply.to@newsgroup> wrote in message
news:uk**************@TK2MSFTNGP09.phx.gbl...
Hi,

lets say that i have class (C#) which will create some kind of communication chanel, which is very expensive in terms of computer resources, and
therefore should be closed, when no longer needed. I have a method which
will create this chanel and a method which will close/release it.

My question is: is there a place where i can release this chanel if user
donīt call my release method? Can i write something like this:

public class MyClass {
// My communication chanel
private TheChannel m_Channel;

public MyClass() {
m_Channel = null;
}

~MyClass() {
if( m_Channel != null ) {
// Release channel
}
}

public void CreateChannel() { //... }
public void CloseChannel() { //... }
}

This method seems to work! But documentation says that "C# has no
destructor." It also says that is should use Dispose-method, like all the
.NET classes do, but it doesn't work!
Kimmo Laine

Nov 16 '05 #3
Dmitriy Lapshin [C# / .NET MVP] <x-****@no-spam-please.hotpop.com>
wrote:
Please refer to the MSDN library on implementing the IDisposable interface
in components and the related design pattern.


Namely at:

http://tinyurl.com/2k6e

Note that your MyClass class probably *shouldn't* have a finalizer -
just a Dispose method. Your TheChannel class could have a finalizer
though.

I'm coming round to the idea that actually, all finalizers should be
something like:

#if DEBUG
~Foo
{
System.Windows.Forms.MessageBox.Show ("Dispose not called on Foo");
}
#endif

Finalizers shouldn't end up being used - if one gets called, that
usually means there's a bug in the program (assuming that Dispose
correctly suppresses finalization) and that bug may well bite you (at a
hard-to-detect time) if you don't fix it. So, instead of pretending
that the bug doesn't exist (by attempting to patch things up in the
finalizer), draw a developer's attention to the fact that he's got the
bug in the first place.

It's a bit of an aggressive approach, but it does appeal...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #4
Hi Dmitriy,

i did it but it doesn't work:

public class TestClass : IDisposable {
public TestClass() {
const string QNAME = @".\private$\Deltest";
MessageQueue mq = null;
if( MessageQueue.Exists( QNAME ) ) {
mq = new MessageQueue( QNAME );
} else {
mq = MessageQueue.Create( QNAME );
}
}

~TestClass() {
//Dispose( false );
}

protected virtual void Dispose( bool publicDispose ) {
if( publicDispose ) {
const string QNAME = @".\private$\Deltest";
if( MessageQueue.Exists( QNAME ) ) {
MessageQueue.Delete( QNAME );
}
}
}

public void Dispose() {
Dispose( true );
}
}

In this test, the message queue is not deleted.
Kimmo Laine


"Dmitriy Lapshin [C# / .NET MVP]" <x-****@no-spam-please.hotpop.com> wrote
in message news:uR**************@tk2msftngp13.phx.gbl...
Hi,

Please refer to the MSDN library on implementing the IDisposable interface
in components and the related design pattern.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://www.x-unity.net/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Kimmo Laine" <reply.to@newsgroup> wrote in message
news:uk**************@TK2MSFTNGP09.phx.gbl...
Hi,

lets say that i have class (C#) which will create some kind of

communication
chanel, which is very expensive in terms of computer resources, and
therefore should be closed, when no longer needed. I have a method which
will create this chanel and a method which will close/release it.

My question is: is there a place where i can release this chanel if user
donīt call my release method? Can i write something like this:

public class MyClass {
// My communication chanel
private TheChannel m_Channel;

public MyClass() {
m_Channel = null;
}

~MyClass() {
if( m_Channel != null ) {
// Release channel
}
}

public void CreateChannel() { //... }
public void CloseChannel() { //... }
}

This method seems to work! But documentation says that "C# has no
destructor." It also says that is should use Dispose-method, like all the .NET classes do, but it doesn't work!
Kimmo Laine

Nov 16 '05 #5
what you read was correct: C# doesn't have destructors.
the destructor-syntax is a shortcut to implement the "finalize" method that
is called by the GC when the object gets cleaned up.
Unlike destructors, you cannot tell when a finalizer will be called, nor
what thread will call it, and finalizers make the GC less efficient - so you
should avoid them where you can (i.e. call SuppressFinalize in you
Dispose/Close/Release method).

And the "Dispose" pattern works fine if your class's clients call the
Dispose method.

Niki

"Kimmo Laine" <reply.to@newsgroup> wrote in
news:uk**************@TK2MSFTNGP09.phx.gbl...
Hi,

lets say that i have class (C#) which will create some kind of communication chanel, which is very expensive in terms of computer resources, and
therefore should be closed, when no longer needed. I have a method which
will create this chanel and a method which will close/release it.

My question is: is there a place where i can release this chanel if user
donīt call my release method? Can i write something like this:

public class MyClass {
// My communication chanel
private TheChannel m_Channel;

public MyClass() {
m_Channel = null;
}

~MyClass() {
if( m_Channel != null ) {
// Release channel
}
}

public void CreateChannel() { //... }
public void CloseChannel() { //... }
}

This method seems to work! But documentation says that "C# has no
destructor." It also says that is should use Dispose-method, like all the
.NET classes do, but it doesn't work!
Kimmo Laine

Nov 16 '05 #6
Jon,
I totally agree with you on the fact that finalizers should seldom
be used, but your explanation thre threw me for a toss :)
<snip>
So, instead of pretending
that the bug doesn't exist (by attempting to patch things up in the
finalizer), draw a developer's attention to the fact that he's got the
bug in the first place.

<snip>

What do you mean when you say "pretend that the bug doesnt exist"?!!

--
Regards,
Dilip Krishnan
MCAD, MCSD.net
dilipdotnet at apdiya dot com
Nov 16 '05 #7
Dilip Krishnan <dilipdotnet..NOSPAM..@apdiya.com> wrote:
I totally agree with you on the fact that finalizers should seldom
be used, but your explanation thre threw me for a toss :)

<snip>
So, instead of pretending
that the bug doesn't exist (by attempting to patch things up in the
finalizer), draw a developer's attention to the fact that he's got the
bug in the first place.

<snip>

What do you mean when you say "pretend that the bug doesnt exist"?!!


If you fail to call Close/Dispose on a stream, you have a bug. However,
the framework will automatically close the stream for you when its
finalizer is called - so most of the time, it looks like you don't have
a bug. You still do, it's just not very obvious.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #8
For debugging, your suggestion is very good. However, one needs to consider
who will be using the object with the finalizer. If the object will be
ditributed in a compiled form for other programmers to consume, you should
still have the finalizer do cleanup.

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Dmitriy Lapshin [C# / .NET MVP] <x-****@no-spam-please.hotpop.com>
wrote:
Please refer to the MSDN library on implementing the IDisposable interface in components and the related design pattern.


Namely at:

http://tinyurl.com/2k6e

Note that your MyClass class probably *shouldn't* have a finalizer -
just a Dispose method. Your TheChannel class could have a finalizer
though.

I'm coming round to the idea that actually, all finalizers should be
something like:

#if DEBUG
~Foo
{
System.Windows.Forms.MessageBox.Show ("Dispose not called on Foo");
}
#endif

Finalizers shouldn't end up being used - if one gets called, that
usually means there's a bug in the program (assuming that Dispose
correctly suppresses finalization) and that bug may well bite you (at a
hard-to-detect time) if you don't fix it. So, instead of pretending
that the bug doesn't exist (by attempting to patch things up in the
finalizer), draw a developer's attention to the fact that he's got the
bug in the first place.

It's a bit of an aggressive approach, but it does appeal...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 16 '05 #9
Kimmo,

You need to call Dispose explicitly somewhere in your program. Did you do
this?

I also agree with Jon that pretty much the only thing you should do in the
finalizer is to verify that Dispose was called. If it was not called, then
you effectively have a bug and you should show an error message or do
something else to alert the programmer to the fact.

Regards,
Sami

"Kimmo Laine" <reply.to@newsgroup> wrote in message
news:uF**************@TK2MSFTNGP09.phx.gbl...
Hi Dmitriy,

i did it but it doesn't work:

public class TestClass : IDisposable {
public TestClass() {
const string QNAME = @".\private$\Deltest";
MessageQueue mq = null;
if( MessageQueue.Exists( QNAME ) ) {
mq = new MessageQueue( QNAME );
} else {
mq = MessageQueue.Create( QNAME );
}
}

~TestClass() {
//Dispose( false );
}

protected virtual void Dispose( bool publicDispose ) {
if( publicDispose ) {
const string QNAME = @".\private$\Deltest";
if( MessageQueue.Exists( QNAME ) ) {
MessageQueue.Delete( QNAME );
}
}
}

public void Dispose() {
Dispose( true );
}
}

In this test, the message queue is not deleted.
Kimmo Laine


"Dmitriy Lapshin [C# / .NET MVP]" <x-****@no-spam-please.hotpop.com> wrote
in message news:uR**************@tk2msftngp13.phx.gbl...
Hi,

Please refer to the MSDN library on implementing the IDisposable interface
in components and the related design pattern.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://www.x-unity.net/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Kimmo Laine" <reply.to@newsgroup> wrote in message
news:uk**************@TK2MSFTNGP09.phx.gbl...
Hi,

lets say that i have class (C#) which will create some kind of

communication
chanel, which is very expensive in terms of computer resources, and
therefore should be closed, when no longer needed. I have a method which will create this chanel and a method which will close/release it.

My question is: is there a place where i can release this chanel if user donīt call my release method? Can i write something like this:

public class MyClass {
// My communication chanel
private TheChannel m_Channel;

public MyClass() {
m_Channel = null;
}

~MyClass() {
if( m_Channel != null ) {
// Release channel
}
}

public void CreateChannel() { //... }
public void CloseChannel() { //... }
}

This method seems to work! But documentation says that "C# has no
destructor." It also says that is should use Dispose-method, like all

the .NET classes do, but it doesn't work!
Kimmo Laine

Nov 16 '05 #10
Scott English <no****@nospam.com> wrote:
For debugging, your suggestion is very good. However, one needs to consider
who will be using the object with the finalizer. If the object will be
ditributed in a compiled form for other programmers to consume, you should
still have the finalizer do cleanup.


I'm not entirely convinced - 3rd party developers are in just as much
need of being told clearly that their program is broken as anyone else.

Getting the finalizer to do clean up just makes the problem harder to
spot - it goes from "broken always" to "broken for some indeterminate
length of time".

As I say, it's a bit of an aggressive stance, and I haven't actually
taken it yet in code I've written (not having had to include any
finalizers myself, that I can remember) but I think it has its merits.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Rajesh Garg | last post by:
Can we have private constructors and destructors? IF yes what is the use of such constructors or destructors.....in the sense where can these be implemented in a system................. I have...
3
by: Nuno Barros | last post by:
Cn someone tell me if when i call the destructor of a derivated class, the destructor of the base class is called implicitly? Or shall i call the destructor by myself? Thanks in advance ...
12
by: Ross Boylan | last post by:
I am trying to understand under what circumstances destructors get called with std::vector. I have an application in which I will put real objects, not just pointers, in the vector. 1. The...
8
by: johny smith | last post by:
If I have a simple class with say a couple of integers only is there any need for me to provide a destructor? thanks!
7
by: qazmlp | last post by:
When a member function is declared as virtual in the base class, the derived class versions of it are always treated as virtual. I am just wondering, why the same concept was not used for the...
26
by: Michi Henning | last post by:
I've been having problem with destructors in the context of having ported C# code developed under .NET to Mono. What happens is that, on a dual-CPU machine, various parts of the code crash randomly...
8
by: Edward Diener | last post by:
I have a __value class which uses some legacy C++ code. So I wrapped the legacy C++ code in another __nogc class and have a pointer to that class as a member of my __value class. When the __value...
3
by: alex.gman | last post by:
If I have code like this int f() { // ... stuff ... g(); if(x > 0) return (x+4); // ... more stuff ... always_call(z); return y; }
6
by: mlw | last post by:
Could someone explain why there is no destructor in Java classes? There are many times you need to be called WHEN an object goes out of scope and not when it will eventally be freed.
6
by: Jeff Newman | last post by:
Hello, Could anyone explain to me why the following class's destructor shows up as having multiple branches? (At least as judged by gcov 4.1.2 when compiled with gcc 4.1.2 ): struct blah {...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.