473,395 Members | 1,578 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,395 software developers and data experts.

Destructor and garbagecollector

Hi,

I have written a dotnet class that in its constructor consumes a license
from a central license pool. In the destructor it free the license again.
But since I don't know when the destructor is called (that is up to the
garbage collector) the object (and hence the application) consume a license
although it is not in use any more.

I could of course write a specific "logoff" method to run the specific part
of the destructor code that frees the license, but then I have to deal with
an object that is "de-initialized" and therefore not usable.

Is there any other place to implement destructor code that are always called
immediately when the object is deleted?

Peter
Nov 17 '05 #1
13 1433
Hi,

Check out the Dispose pattern (Google for "Dispose pattern MSDN" without the
quotes and you should find it). There is no way to get the same behaviour as
C++ stack objects, but Dispose is the recognized way of getting stuff to
release resources in a timely fashion.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Hi,

I have written a dotnet class that in its constructor consumes a license
from a central license pool. In the destructor it free the license again.
But since I don't know when the destructor is called (that is up to the
garbage collector) the object (and hence the application) consume a license although it is not in use any more.

I could of course write a specific "logoff" method to run the specific part of the destructor code that frees the license, but then I have to deal with an object that is "de-initialized" and therefore not usable.

Is there any other place to implement destructor code that are always called immediately when the object is deleted?

Peter

Nov 17 '05 #2
Hi Steve,

Thanks for your reply. I guess that is the way I have to do it. But then I
need to add code to all the method (and properties) to check if the Dispose
has been called,- and if so throw an exception. The nice thing about the
destructor is that the object simply no longer exist so the methods can not
be called.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:Ot*************@tk2msftngp13.phx.gbl...
Hi,

Check out the Dispose pattern (Google for "Dispose pattern MSDN" without the quotes and you should find it). There is no way to get the same behaviour as C++ stack objects, but Dispose is the recognized way of getting stuff to
release resources in a timely fashion.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Hi,

I have written a dotnet class that in its constructor consumes a license
from a central license pool. In the destructor it free the license again. But since I don't know when the destructor is called (that is up to the
garbage collector) the object (and hence the application) consume a

license
although it is not in use any more.

I could of course write a specific "logoff" method to run the specific

part
of the destructor code that frees the license, but then I have to deal

with
an object that is "de-initialized" and therefore not usable.

Is there any other place to implement destructor code that are always

called
immediately when the object is deleted?

Peter


Nov 17 '05 #3
Hi,

The Dispose pattern helps you cope with that - it should be safe to call it
multiple times without a problem. As long as you know when you're finished
with something it should work. Incidentally, having something just suddenly
not be there isn't a great way to be done with it - if you have something
storing pointers to objects and the things pointed to aren't there any more,
you'll get null pointer exceptions. It sounds like you might want to use
something similar to a weak pointer (or weak reference, the .NET stuff calls
it). I've never used them in MC++ but the gist is that weak pointers will
not keep an object alive as far as the GC is concerned, but if the object is
still alive and you try to use it from the weak pointer it will create a
strong pointer for you to use. If you're using unmanaged C++ the Boost
library has a great imlpementation; otherwise check out the .NET docs. for
'weak references'.

Additionally, you may want to consider some kind of messaging system to let
the container know that something it should be storing doesn't exist any
more. Maybe you can post simplified code here so I can get a better idea of
what you're doing?

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:uN**************@tk2msftngp13.phx.gbl...
Hi Steve,

Thanks for your reply. I guess that is the way I have to do it. But then I
need to add code to all the method (and properties) to check if the Dispose has been called,- and if so throw an exception. The nice thing about the
destructor is that the object simply no longer exist so the methods can not be called.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:Ot*************@tk2msftngp13.phx.gbl...
Hi,

Check out the Dispose pattern (Google for "Dispose pattern MSDN" without the
quotes and you should find it). There is no way to get the same behaviour as
C++ stack objects, but Dispose is the recognized way of getting stuff to
release resources in a timely fashion.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Hi,

I have written a dotnet class that in its constructor consumes a license from a central license pool. In the destructor it free the license

again. But since I don't know when the destructor is called (that is up to the garbage collector) the object (and hence the application) consume a

license
although it is not in use any more.

I could of course write a specific "logoff" method to run the specific

part
of the destructor code that frees the license, but then I have to deal

with
an object that is "de-initialized" and therefore not usable.

Is there any other place to implement destructor code that are always

called
immediately when the object is deleted?

Peter



Nov 17 '05 #4
Hi Steve,

Thanks a lot for your reply.
My constructor connects to a server and consume a license. If this succeed I
now have a "connection" object with methods to get work done on the server
(e.g: search for something on the server by calling ConObj.Find(....)).

If the user of my library (that is the programmer) calls Dispose (release
the license and disconnect from the server) and then later try to call the
Find method it will fail (somehow) because the connection to the server is
gone. It would be nice if all methods would throw the same
"ObjectHasBeenDisposed" exception but that would require me to make a check
in all methods. Alternatively the programmer must be prepared for a number
of different exception if he keeps working on an object that has been
disposed.

Again thanks.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:uP**************@TK2MSFTNGP12.phx.gbl...
Hi,

The Dispose pattern helps you cope with that - it should be safe to call it multiple times without a problem. As long as you know when you're finished
with something it should work. Incidentally, having something just suddenly not be there isn't a great way to be done with it - if you have something
storing pointers to objects and the things pointed to aren't there any more, you'll get null pointer exceptions. It sounds like you might want to use
something similar to a weak pointer (or weak reference, the .NET stuff calls it). I've never used them in MC++ but the gist is that weak pointers will
not keep an object alive as far as the GC is concerned, but if the object is still alive and you try to use it from the weak pointer it will create a
strong pointer for you to use. If you're using unmanaged C++ the Boost
library has a great imlpementation; otherwise check out the .NET docs. for
'weak references'.

Additionally, you may want to consider some kind of messaging system to let the container know that something it should be storing doesn't exist any
more. Maybe you can post simplified code here so I can get a better idea of what you're doing?

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:uN**************@tk2msftngp13.phx.gbl...
Hi Steve,

Thanks for your reply. I guess that is the way I have to do it. But then I
need to add code to all the method (and properties) to check if the

Dispose
has been called,- and if so throw an exception. The nice thing about the
destructor is that the object simply no longer exist so the methods can

not
be called.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:Ot*************@tk2msftngp13.phx.gbl...
Hi,

Check out the Dispose pattern (Google for "Dispose pattern MSDN" without
the
quotes and you should find it). There is no way to get the same

behaviour
as
C++ stack objects, but Dispose is the recognized way of getting stuff

to release resources in a timely fashion.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
> Hi,
>
> I have written a dotnet class that in its constructor consumes a

license > from a central license pool. In the destructor it free the license

again.
> But since I don't know when the destructor is called (that is up to the > garbage collector) the object (and hence the application) consume a
license
> although it is not in use any more.
>
> I could of course write a specific "logoff" method to run the specific part
> of the destructor code that frees the license, but then I have to deal with
> an object that is "de-initialized" and therefore not usable.
>
> Is there any other place to implement destructor code that are always called
> immediately when the object is deleted?
>
> Peter
>
>



Nov 17 '05 #5
Hi,

It sounds as though instead of just keeping the connection as a member state
you could do with having it wrapped somewhere, with an accessor function.
The accessor function can then check whether the connection exists.
Something like what's below (excuse any errors, I'm doing this in between
links). This way, you need to put your exception call in one place and it
also breaks things up a bit. Really, if the user of your lib calls Dispose()
it implies they've got no use for it. Using a Disposed object is not a good
thing to do. Instead, you may just want to have Connect and Disconnect
functions. What's the context for all this?

__gc class ConnectionWrapper
{
void DisposeConnection()
{
conn->Dispose();
conn = 0;
}

void CreateConnection()
{
....
}

Connection *GetConnection()
{
if ( conn )
{
return conn;
}
else
{
throw HorribleException; // Or CreateConnection, whichever
you want to do.
}
}
private:
Connection *conn;
}

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
Hi Steve,

Thanks a lot for your reply.
My constructor connects to a server and consume a license. If this succeed I now have a "connection" object with methods to get work done on the server
(e.g: search for something on the server by calling ConObj.Find(....)).

If the user of my library (that is the programmer) calls Dispose (release
the license and disconnect from the server) and then later try to call the
Find method it will fail (somehow) because the connection to the server is
gone. It would be nice if all methods would throw the same
"ObjectHasBeenDisposed" exception but that would require me to make a check in all methods. Alternatively the programmer must be prepared for a number
of different exception if he keeps working on an object that has been
disposed.

Again thanks.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:uP**************@TK2MSFTNGP12.phx.gbl...
Hi,

The Dispose pattern helps you cope with that - it should be safe to call it
multiple times without a problem. As long as you know when you're finished
with something it should work. Incidentally, having something just

suddenly
not be there isn't a great way to be done with it - if you have something storing pointers to objects and the things pointed to aren't there any

more,
you'll get null pointer exceptions. It sounds like you might want to use
something similar to a weak pointer (or weak reference, the .NET stuff

calls
it). I've never used them in MC++ but the gist is that weak pointers will not keep an object alive as far as the GC is concerned, but if the object is
still alive and you try to use it from the weak pointer it will create a
strong pointer for you to use. If you're using unmanaged C++ the Boost
library has a great imlpementation; otherwise check out the .NET docs.
for 'weak references'.

Additionally, you may want to consider some kind of messaging system to

let
the container know that something it should be storing doesn't exist any
more. Maybe you can post simplified code here so I can get a better idea

of
what you're doing?

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:uN**************@tk2msftngp13.phx.gbl...
Hi Steve,

Thanks for your reply. I guess that is the way I have to do it. But then I need to add code to all the method (and properties) to check if the Dispose
has been called,- and if so throw an exception. The nice thing about
the destructor is that the object simply no longer exist so the methods can
not
be called.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:Ot*************@tk2msftngp13.phx.gbl...
> Hi,
>
> Check out the Dispose pattern (Google for "Dispose pattern MSDN" without the
> quotes and you should find it). There is no way to get the same

behaviour
as
> C++ stack objects, but Dispose is the recognized way of getting
stuff to > release resources in a timely fashion.
>
> Steve
>
> "Peter Hemmingsen" <ph*@softco.dk> wrote in message
> news:%2****************@TK2MSFTNGP10.phx.gbl...
> > Hi,
> >
> > I have written a dotnet class that in its constructor consumes a

license
> > from a central license pool. In the destructor it free the license
again.
> > But since I don't know when the destructor is called (that is up
to the
> > garbage collector) the object (and hence the application) consume

a > license
> > although it is not in use any more.
> >
> > I could of course write a specific "logoff" method to run the

specific > part
> > of the destructor code that frees the license, but then I have to deal > with
> > an object that is "de-initialized" and therefore not usable.
> >
> > Is there any other place to implement destructor code that are always > called
> > immediately when the object is deleted?
> >
> > Peter
> >
> >
>
>



Nov 17 '05 #6
Hi Steve,

We are developing a client/server based document management system (first
version released back in 1988) so the server code and the client library
(using RPC) is developed in C. We have know wrapped the client C library
into MC++ and then clients can be written in C#.

In fact I already have a GetConnection method. It is static and provides a
singleton scheme for the connection object. However I can't avoid the
programmer to write something like this:

SEConnection con = SEConnection.GetConnection();
....
con.Dispose();

con.Find(...); // Horrible error

but I guess that is up to the programmer never to use a disposed object.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:OL**************@tk2msftngp13.phx.gbl...
Hi,

It sounds as though instead of just keeping the connection as a member state you could do with having it wrapped somewhere, with an accessor function.
The accessor function can then check whether the connection exists.
Something like what's below (excuse any errors, I'm doing this in between
links). This way, you need to put your exception call in one place and it
also breaks things up a bit. Really, if the user of your lib calls Dispose() it implies they've got no use for it. Using a Disposed object is not a good thing to do. Instead, you may just want to have Connect and Disconnect
functions. What's the context for all this?

__gc class ConnectionWrapper
{
void DisposeConnection()
{
conn->Dispose();
conn = 0;
}

void CreateConnection()
{
....
}

Connection *GetConnection()
{
if ( conn )
{
return conn;
}
else
{
throw HorribleException; // Or CreateConnection, whichever
you want to do.
}
}
private:
Connection *conn;
}

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
Hi Steve,

Thanks a lot for your reply.
My constructor connects to a server and consume a license. If this succeed
I
now have a "connection" object with methods to get work done on the server (e.g: search for something on the server by calling ConObj.Find(....)).

If the user of my library (that is the programmer) calls Dispose (release the license and disconnect from the server) and then later try to call the Find method it will fail (somehow) because the connection to the server is gone. It would be nice if all methods would throw the same
"ObjectHasBeenDisposed" exception but that would require me to make a check
in all methods. Alternatively the programmer must be prepared for a number of different exception if he keeps working on an object that has been
disposed.

Again thanks.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:uP**************@TK2MSFTNGP12.phx.gbl...
Hi,

The Dispose pattern helps you cope with that - it should be safe to call
it
multiple times without a problem. As long as you know when you're finished with something it should work. Incidentally, having something just

suddenly
not be there isn't a great way to be done with it - if you have something storing pointers to objects and the things pointed to aren't there any

more,
you'll get null pointer exceptions. It sounds like you might want to
use something similar to a weak pointer (or weak reference, the .NET stuff

calls
it). I've never used them in MC++ but the gist is that weak pointers

will not keep an object alive as far as the GC is concerned, but if the object
is
still alive and you try to use it from the weak pointer it will create a strong pointer for you to use. If you're using unmanaged C++ the Boost
library has a great imlpementation; otherwise check out the .NET docs.

for 'weak references'.

Additionally, you may want to consider some kind of messaging system to let
the container know that something it should be storing doesn't exist
any more. Maybe you can post simplified code here so I can get a better idea
of
what you're doing?

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:uN**************@tk2msftngp13.phx.gbl...
> Hi Steve,
>
> Thanks for your reply. I guess that is the way I have to do it. But then
I
> need to add code to all the method (and properties) to check if the
Dispose
> has been called,- and if so throw an exception. The nice thing about

the > destructor is that the object simply no longer exist so the methods can not
> be called.
>
> Peter
>
> "Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
> news:Ot*************@tk2msftngp13.phx.gbl...
> > Hi,
> >
> > Check out the Dispose pattern (Google for "Dispose pattern MSDN"

without
> the
> > quotes and you should find it). There is no way to get the same
behaviour
> as
> > C++ stack objects, but Dispose is the recognized way of getting stuff
to
> > release resources in a timely fashion.
> >
> > Steve
> >
> > "Peter Hemmingsen" <ph*@softco.dk> wrote in message
> > news:%2****************@TK2MSFTNGP10.phx.gbl...
> > > Hi,
> > >
> > > I have written a dotnet class that in its constructor consumes a
license
> > > from a central license pool. In the destructor it free the

license > again.
> > > But since I don't know when the destructor is called (that is up

to the
> > > garbage collector) the object (and hence the application)
consume a > > license
> > > although it is not in use any more.
> > >
> > > I could of course write a specific "logoff" method to run the

specific
> > part
> > > of the destructor code that frees the license, but then I have

to deal
> > with
> > > an object that is "de-initialized" and therefore not usable.
> > >
> > > Is there any other place to implement destructor code that are

always
> > called
> > > immediately when the object is deleted?
> > >
> > > Peter
> > >
> > >
> >
> >
>
>



Nov 17 '05 #7
Hi,

Yeah, the programmer should spot that (and more importantly it will be very
obvious at first test that something's wrong). But using C++ stack objects
wouldn't help this - you'd get

{
SEConnection con = SEConnection.GetConnection();
...
}
con.Find();

and get a compiler error. This might be slightly better than the runtime
error you'd get using Dispose but it's not ideal. Incidentally, you can
still scope the calls so the con.Find() line won't compile. Dispose is used
as a way of releasing resources in a timely fashion rather than waiting for
the garbage collector.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:u6**************@TK2MSFTNGP11.phx.gbl...
Hi Steve,

We are developing a client/server based document management system (first
version released back in 1988) so the server code and the client library
(using RPC) is developed in C. We have know wrapped the client C library
into MC++ and then clients can be written in C#.

In fact I already have a GetConnection method. It is static and provides a
singleton scheme for the connection object. However I can't avoid the
programmer to write something like this:

SEConnection con = SEConnection.GetConnection();
...
con.Dispose();

con.Find(...); // Horrible error

but I guess that is up to the programmer never to use a disposed object.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:OL**************@tk2msftngp13.phx.gbl...
Hi,

It sounds as though instead of just keeping the connection as a member state
you could do with having it wrapped somewhere, with an accessor function.
The accessor function can then check whether the connection exists.
Something like what's below (excuse any errors, I'm doing this in between links). This way, you need to put your exception call in one place and it also breaks things up a bit. Really, if the user of your lib calls

Dispose()
it implies they've got no use for it. Using a Disposed object is not a

good
thing to do. Instead, you may just want to have Connect and Disconnect
functions. What's the context for all this?

__gc class ConnectionWrapper
{
void DisposeConnection()
{
conn->Dispose();
conn = 0;
}

void CreateConnection()
{
....
}

Connection *GetConnection()
{
if ( conn )
{
return conn;
}
else
{
throw HorribleException; // Or CreateConnection, whichever you want to do.
}
}
private:
Connection *conn;
}

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
Hi Steve,

Thanks a lot for your reply.
My constructor connects to a server and consume a license. If this succeed
I
now have a "connection" object with methods to get work done on the

server (e.g: search for something on the server by calling ConObj.Find(....)).
If the user of my library (that is the programmer) calls Dispose (release the license and disconnect from the server) and then later try to call the Find method it will fail (somehow) because the connection to the server is
gone. It would be nice if all methods would throw the same
"ObjectHasBeenDisposed" exception but that would require me to make a check
in all methods. Alternatively the programmer must be prepared for a number of different exception if he keeps working on an object that has been
disposed.

Again thanks.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:uP**************@TK2MSFTNGP12.phx.gbl...
> Hi,
>
> The Dispose pattern helps you cope with that - it should be safe to call it
> multiple times without a problem. As long as you know when you're

finished
> with something it should work. Incidentally, having something just
suddenly
> not be there isn't a great way to be done with it - if you have

something
> storing pointers to objects and the things pointed to aren't there
any more,
> you'll get null pointer exceptions. It sounds like you might want to

use > something similar to a weak pointer (or weak reference, the .NET stuff calls
> it). I've never used them in MC++ but the gist is that weak pointers

will
> not keep an object alive as far as the GC is concerned, but if the

object
is
> still alive and you try to use it from the weak pointer it will create a
> strong pointer for you to use. If you're using unmanaged C++ the
Boost > library has a great imlpementation; otherwise check out the .NET docs. for
> 'weak references'.
>
> Additionally, you may want to consider some kind of messaging system to let
> the container know that something it should be storing doesn't exist any > more. Maybe you can post simplified code here so I can get a better idea of
> what you're doing?
>
> Steve
>
> "Peter Hemmingsen" <ph*@softco.dk> wrote in message
> news:uN**************@tk2msftngp13.phx.gbl...
> > Hi Steve,
> >
> > Thanks for your reply. I guess that is the way I have to do it.
But then
I
> > need to add code to all the method (and properties) to check if
the > Dispose
> > has been called,- and if so throw an exception. The nice thing about the
> > destructor is that the object simply no longer exist so the
methods can
> not
> > be called.
> >
> > Peter
> >
> > "Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in
message > > news:Ot*************@tk2msftngp13.phx.gbl...
> > > Hi,
> > >
> > > Check out the Dispose pattern (Google for "Dispose pattern MSDN"
without
> > the
> > > quotes and you should find it). There is no way to get the same
> behaviour
> > as
> > > C++ stack objects, but Dispose is the recognized way of getting

stuff
to
> > > release resources in a timely fashion.
> > >
> > > Steve
> > >
> > > "Peter Hemmingsen" <ph*@softco.dk> wrote in message
> > > news:%2****************@TK2MSFTNGP10.phx.gbl...
> > > > Hi,
> > > >
> > > > I have written a dotnet class that in its constructor consumes a > license
> > > > from a central license pool. In the destructor it free the

license > > again.
> > > > But since I don't know when the destructor is called (that is
up to
> the
> > > > garbage collector) the object (and hence the application)

consume
a
> > > license
> > > > although it is not in use any more.
> > > >
> > > > I could of course write a specific "logoff" method to run the
specific
> > > part
> > > > of the destructor code that frees the license, but then I have

to deal
> > > with
> > > > an object that is "de-initialized" and therefore not usable.
> > > >
> > > > Is there any other place to implement destructor code that are
always
> > > called
> > > > immediately when the object is deleted?
> > > >
> > > > Peter
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 17 '05 #8
Thanks for all you comments.

One last question:

What do I gain from deriving from IDisposable? (As apposed to just making a
public Dispose method)

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:OS**************@tk2msftngp13.phx.gbl...
Hi,

Yeah, the programmer should spot that (and more importantly it will be very obvious at first test that something's wrong). But using C++ stack objects
wouldn't help this - you'd get

{
SEConnection con = SEConnection.GetConnection();
...
}
con.Find();

and get a compiler error. This might be slightly better than the runtime
error you'd get using Dispose but it's not ideal. Incidentally, you can
still scope the calls so the con.Find() line won't compile. Dispose is used as a way of releasing resources in a timely fashion rather than waiting for the garbage collector.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:u6**************@TK2MSFTNGP11.phx.gbl...
Hi Steve,

We are developing a client/server based document management system (first
version released back in 1988) so the server code and the client library
(using RPC) is developed in C. We have know wrapped the client C library
into MC++ and then clients can be written in C#.

In fact I already have a GetConnection method. It is static and provides a singleton scheme for the connection object. However I can't avoid the
programmer to write something like this:

SEConnection con = SEConnection.GetConnection();
...
con.Dispose();

con.Find(...); // Horrible error

but I guess that is up to the programmer never to use a disposed object.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:OL**************@tk2msftngp13.phx.gbl...
Hi,

It sounds as though instead of just keeping the connection as a member state
you could do with having it wrapped somewhere, with an accessor function. The accessor function can then check whether the connection exists.
Something like what's below (excuse any errors, I'm doing this in between links). This way, you need to put your exception call in one place and it also breaks things up a bit. Really, if the user of your lib calls

Dispose()
it implies they've got no use for it. Using a Disposed object is not a

good
thing to do. Instead, you may just want to have Connect and Disconnect
functions. What's the context for all this?

__gc class ConnectionWrapper
{
void DisposeConnection()
{
conn->Dispose();
conn = 0;
}

void CreateConnection()
{
....
}

Connection *GetConnection()
{
if ( conn )
{
return conn;
}
else
{
throw HorribleException; // Or CreateConnection, whichever you want to do.
}
}
private:
Connection *conn;
}

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
> Hi Steve,
>
> Thanks a lot for your reply.
> My constructor connects to a server and consume a license. If this

succeed
I
> now have a "connection" object with methods to get work done on the

server
> (e.g: search for something on the server by calling ConObj.Find(....)). >
> If the user of my library (that is the programmer) calls Dispose

(release
> the license and disconnect from the server) and then later try to call the
> Find method it will fail (somehow) because the connection to the server
is
> gone. It would be nice if all methods would throw the same
> "ObjectHasBeenDisposed" exception but that would require me to make
a check
> in all methods. Alternatively the programmer must be prepared for a

number
> of different exception if he keeps working on an object that has been > disposed.
>
> Again thanks.
>
> Peter
>
> "Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
> news:uP**************@TK2MSFTNGP12.phx.gbl...
> > Hi,
> >
> > The Dispose pattern helps you cope with that - it should be safe to call
> it
> > multiple times without a problem. As long as you know when you're
finished
> > with something it should work. Incidentally, having something just
> suddenly
> > not be there isn't a great way to be done with it - if you have
something
> > storing pointers to objects and the things pointed to aren't there any > more,
> > you'll get null pointer exceptions. It sounds like you might want
to use
> > something similar to a weak pointer (or weak reference, the .NET stuff > calls
> > it). I've never used them in MC++ but the gist is that weak
pointers will
> > not keep an object alive as far as the GC is concerned, but if the
object
> is
> > still alive and you try to use it from the weak pointer it will

create
a
> > strong pointer for you to use. If you're using unmanaged C++ the

Boost > > library has a great imlpementation; otherwise check out the .NET docs. for
> > 'weak references'.
> >
> > Additionally, you may want to consider some kind of messaging system to
> let
> > the container know that something it should be storing doesn't
exist
any
> > more. Maybe you can post simplified code here so I can get a
better idea
> of
> > what you're doing?
> >
> > Steve
> >
> > "Peter Hemmingsen" <ph*@softco.dk> wrote in message
> > news:uN**************@tk2msftngp13.phx.gbl...
> > > Hi Steve,
> > >
> > > Thanks for your reply. I guess that is the way I have to do it. But then
> I
> > > need to add code to all the method (and properties) to check if the > > Dispose
> > > has been called,- and if so throw an exception. The nice thing about the
> > > destructor is that the object simply no longer exist so the methods can
> > not
> > > be called.
> > >
> > > Peter
> > >
> > > "Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message > > > news:Ot*************@tk2msftngp13.phx.gbl...
> > > > Hi,
> > > >
> > > > Check out the Dispose pattern (Google for "Dispose pattern
MSDN" > without
> > > the
> > > > quotes and you should find it). There is no way to get the same > > behaviour
> > > as
> > > > C++ stack objects, but Dispose is the recognized way of getting stuff
> to
> > > > release resources in a timely fashion.
> > > >
> > > > Steve
> > > >
> > > > "Peter Hemmingsen" <ph*@softco.dk> wrote in message
> > > > news:%2****************@TK2MSFTNGP10.phx.gbl...
> > > > > Hi,
> > > > >
> > > > > I have written a dotnet class that in its constructor consumes a > > license
> > > > > from a central license pool. In the destructor it free the license
> > > again.
> > > > > But since I don't know when the destructor is called (that
is up to
> > the
> > > > > garbage collector) the object (and hence the application)

consume
a
> > > > license
> > > > > although it is not in use any more.
> > > > >
> > > > > I could of course write a specific "logoff" method to run

the > specific
> > > > part
> > > > > of the destructor code that frees the license, but then I have to
> deal
> > > > with
> > > > > an object that is "de-initialized" and therefore not usable.
> > > > >
> > > > > Is there any other place to implement destructor code that

are > always
> > > > called
> > > > > immediately when the object is deleted?
> > > > >
> > > > > Peter
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 17 '05 #9
Hi,

Have a look at
http://msdn.microsoft.com/library/de...posemethod.asp

It's basically just a standardised way of doing things (it's a pattern),
though there are probably things the GC can do if it knows a class is
IDisposable. Since it is an 'official' pattern, anyone else looking at your
code will know exactly what it does (assuming it does what it's supposed to
:-) )

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:uY**************@TK2MSFTNGP09.phx.gbl...
Thanks for all you comments.

One last question:

What do I gain from deriving from IDisposable? (As apposed to just making a public Dispose method)

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:OS**************@tk2msftngp13.phx.gbl...
Hi,

Yeah, the programmer should spot that (and more importantly it will be very
obvious at first test that something's wrong). But using C++ stack objects
wouldn't help this - you'd get

{
SEConnection con = SEConnection.GetConnection();
...
}
con.Find();

and get a compiler error. This might be slightly better than the runtime
error you'd get using Dispose but it's not ideal. Incidentally, you can
still scope the calls so the con.Find() line won't compile. Dispose is

used
as a way of releasing resources in a timely fashion rather than waiting

for
the garbage collector.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:u6**************@TK2MSFTNGP11.phx.gbl...
Hi Steve,

We are developing a client/server based document management system (first version released back in 1988) so the server code and the client library (using RPC) is developed in C. We have know wrapped the client C library into MC++ and then clients can be written in C#.

In fact I already have a GetConnection method. It is static and provides a
singleton scheme for the connection object. However I can't avoid the
programmer to write something like this:

SEConnection con = SEConnection.GetConnection();
...
con.Dispose();

con.Find(...); // Horrible error

but I guess that is up to the programmer never to use a disposed
object.
Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:OL**************@tk2msftngp13.phx.gbl...
> Hi,
>
> It sounds as though instead of just keeping the connection as a member state
> you could do with having it wrapped somewhere, with an accessor function.
> The accessor function can then check whether the connection exists.
> Something like what's below (excuse any errors, I'm doing this in

between
> links). This way, you need to put your exception call in one place and it
> also breaks things up a bit. Really, if the user of your lib calls
Dispose()
> it implies they've got no use for it. Using a Disposed object is not
a good
> thing to do. Instead, you may just want to have Connect and Disconnect > functions. What's the context for all this?
>
> __gc class ConnectionWrapper
> {
> void DisposeConnection()
> {
> conn->Dispose();
> conn = 0;
> }
>
> void CreateConnection()
> {
> ....
> }
>
> Connection *GetConnection()
> {
> if ( conn )
> {
> return conn;
> }
> else
> {
> throw HorribleException; // Or CreateConnection,

whichever
> you want to do.
> }
> }
> private:
> Connection *conn;
> }
>
> "Peter Hemmingsen" <ph*@softco.dk> wrote in message
> news:%2****************@TK2MSFTNGP11.phx.gbl...
> > Hi Steve,
> >
> > Thanks a lot for your reply.
> > My constructor connects to a server and consume a license. If this
succeed
> I
> > now have a "connection" object with methods to get work done on the server
> > (e.g: search for something on the server by calling

ConObj.Find(....)).
> >
> > If the user of my library (that is the programmer) calls Dispose
(release
> > the license and disconnect from the server) and then later try to

call the
> > Find method it will fail (somehow) because the connection to the

server
is
> > gone. It would be nice if all methods would throw the same
> > "ObjectHasBeenDisposed" exception but that would require me to make a
> check
> > in all methods. Alternatively the programmer must be prepared for
a number
> > of different exception if he keeps working on an object that has
been > > disposed.
> >
> > Again thanks.
> >
> > Peter
> >
> > "Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message > > news:uP**************@TK2MSFTNGP12.phx.gbl...
> > > Hi,
> > >
> > > The Dispose pattern helps you cope with that - it should be safe to call
> > it
> > > multiple times without a problem. As long as you know when you're > finished
> > > with something it should work. Incidentally, having something just > > suddenly
> > > not be there isn't a great way to be done with it - if you have
> something
> > > storing pointers to objects and the things pointed to aren't there any
> > more,
> > > you'll get null pointer exceptions. It sounds like you might
want to use
> > > something similar to a weak pointer (or weak reference, the .NET

stuff
> > calls
> > > it). I've never used them in MC++ but the gist is that weak pointers > will
> > > not keep an object alive as far as the GC is concerned, but if
the > object
> > is
> > > still alive and you try to use it from the weak pointer it will

create
a
> > > strong pointer for you to use. If you're using unmanaged C++ the

Boost
> > > library has a great imlpementation; otherwise check out the .NET

docs.
> for
> > > 'weak references'.
> > >
> > > Additionally, you may want to consider some kind of messaging system to
> > let
> > > the container know that something it should be storing doesn't exist any
> > > more. Maybe you can post simplified code here so I can get a better idea
> > of
> > > what you're doing?
> > >
> > > Steve
> > >
> > > "Peter Hemmingsen" <ph*@softco.dk> wrote in message
> > > news:uN**************@tk2msftngp13.phx.gbl...
> > > > Hi Steve,
> > > >
> > > > Thanks for your reply. I guess that is the way I have to do it. But
> then
> > I
> > > > need to add code to all the method (and properties) to check
if
the
> > > Dispose
> > > > has been called,- and if so throw an exception. The nice thing

about
> the
> > > > destructor is that the object simply no longer exist so the

methods
> can
> > > not
> > > > be called.
> > > >
> > > > Peter
> > > >
> > > > "Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in

message
> > > > news:Ot*************@tk2msftngp13.phx.gbl...
> > > > > Hi,
> > > > >
> > > > > Check out the Dispose pattern (Google for "Dispose pattern

MSDN" > > without
> > > > the
> > > > > quotes and you should find it). There is no way to get the same > > > behaviour
> > > > as
> > > > > C++ stack objects, but Dispose is the recognized way of getting > stuff
> > to
> > > > > release resources in a timely fashion.
> > > > >
> > > > > Steve
> > > > >
> > > > > "Peter Hemmingsen" <ph*@softco.dk> wrote in message
> > > > > news:%2****************@TK2MSFTNGP10.phx.gbl...
> > > > > > Hi,
> > > > > >
> > > > > > I have written a dotnet class that in its constructor consumes
a
> > > license
> > > > > > from a central license pool. In the destructor it free the
license
> > > > again.
> > > > > > But since I don't know when the destructor is called (that

is
up
> to
> > > the
> > > > > > garbage collector) the object (and hence the application)
consume
> a
> > > > > license
> > > > > > although it is not in use any more.
> > > > > >
> > > > > > I could of course write a specific "logoff" method to run

the > > specific
> > > > > part
> > > > > > of the destructor code that frees the license, but then I have to
> > deal
> > > > > with
> > > > > > an object that is "de-initialized" and therefore not
usable. > > > > > >
> > > > > > Is there any other place to implement destructor code that

are > > always
> > > > > called
> > > > > > immediately when the object is deleted?
> > > > > >
> > > > > > Peter
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 17 '05 #10
Hi,

Have a look at this sample MC++ code:

public __gc class MyTable : public DataTable, public IDisposable {
public:
MyTable() {GC::ReRegisterForFinalize(this); m_p=malloc(1000);};
~MyTable() {GC::SuppressFinalize(this);Dispose();};
virtual void Dispose() {free(m_p);};

private:
void* m_p;
};

First of all the GC::ReRegisterForFinalize in the constructor is required
because the DataTable implementation will always have GC::SuppressFinalize
meaning that the MyTable destructor by default will never be called.

The above code can't compiler because the DataTable has a derived Dispose
method that are marked as sealed.

If I instead of naming my method Dispose name it CleanUp then the user of
MyTable could still just call Dispose (not realizing that there is a CleanUp
method) and then the MyTable unmanaged resources are not released.

Any suggestion?

Peter
Nov 17 '05 #11
The Dispose() method in MarshalByValueComponent should call Dispose(
Boolean ), passing in true. The version with the argument is virtual, so can
be overriden. The docs for MarshalByValueComponent say:

"Notes to Inheritors: When you inherit from this class, you can override
the Dispose, Site, and the GetService methods."

You probably don't want to separately implement IDisposable (I'm surprised
it lets you do that at all) - MarshalByValueComponent implements it, so you
just want to override its Dispose function.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:er**************@TK2MSFTNGP12.phx.gbl...
Hi,

Have a look at this sample MC++ code:

public __gc class MyTable : public DataTable, public IDisposable {
public:
MyTable() {GC::ReRegisterForFinalize(this); m_p=malloc(1000);};
~MyTable() {GC::SuppressFinalize(this);Dispose();};
virtual void Dispose() {free(m_p);};

private:
void* m_p;
};

First of all the GC::ReRegisterForFinalize in the constructor is required
because the DataTable implementation will always have GC::SuppressFinalize
meaning that the MyTable destructor by default will never be called.

The above code can't compiler because the DataTable has a derived Dispose
method that are marked as sealed.

If I instead of naming my method Dispose name it CleanUp then the user of
MyTable could still just call Dispose (not realizing that there is a CleanUp method) and then the MyTable unmanaged resources are not released.

Any suggestion?

Peter

Nov 17 '05 #12
Thanks a lot Steve. Your help is very much appreciated.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:eu**************@TK2MSFTNGP12.phx.gbl...
The Dispose() method in MarshalByValueComponent should call Dispose(
Boolean ), passing in true. The version with the argument is virtual, so can be overriden. The docs for MarshalByValueComponent say:

"Notes to Inheritors: When you inherit from this class, you can override
the Dispose, Site, and the GetService methods."

You probably don't want to separately implement IDisposable (I'm surprised
it lets you do that at all) - MarshalByValueComponent implements it, so you just want to override its Dispose function.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:er**************@TK2MSFTNGP12.phx.gbl...
Hi,

Have a look at this sample MC++ code:

public __gc class MyTable : public DataTable, public IDisposable {
public:
MyTable() {GC::ReRegisterForFinalize(this); m_p=malloc(1000);};
~MyTable() {GC::SuppressFinalize(this);Dispose();};
virtual void Dispose() {free(m_p);};

private:
void* m_p;
};

First of all the GC::ReRegisterForFinalize in the constructor is required because the DataTable implementation will always have GC::SuppressFinalize meaning that the MyTable destructor by default will never be called.

The above code can't compiler because the DataTable has a derived Dispose method that are marked as sealed.

If I instead of naming my method Dispose name it CleanUp then the user of MyTable could still just call Dispose (not realizing that there is a

CleanUp
method) and then the MyTable unmanaged resources are not released.

Any suggestion?

Peter


Nov 17 '05 #13
No probs, these newsgroups are a great resource, and one of the reasons we
develop PC versions of our stuff before OS X releases - the Mac's a great
platform but it's so hard finding any developer resources. Good luck with
things!

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:Oj*************@TK2MSFTNGP09.phx.gbl...
Thanks a lot Steve. Your help is very much appreciated.

Peter

"Steve McLellan" <sjm.NOSPAM AT fixerlabs DOT com> wrote in message
news:eu**************@TK2MSFTNGP12.phx.gbl...
The Dispose() method in MarshalByValueComponent should call Dispose(
Boolean ), passing in true. The version with the argument is virtual, so

can
be overriden. The docs for MarshalByValueComponent say:

"Notes to Inheritors: When you inherit from this class, you can override
the Dispose, Site, and the GetService methods."

You probably don't want to separately implement IDisposable (I'm surprised it lets you do that at all) - MarshalByValueComponent implements it, so

you
just want to override its Dispose function.

Steve

"Peter Hemmingsen" <ph*@softco.dk> wrote in message
news:er**************@TK2MSFTNGP12.phx.gbl...
Hi,

Have a look at this sample MC++ code:

public __gc class MyTable : public DataTable, public IDisposable {
public:
MyTable() {GC::ReRegisterForFinalize(this); m_p=malloc(1000);};
~MyTable() {GC::SuppressFinalize(this);Dispose();};
virtual void Dispose() {free(m_p);};

private:
void* m_p;
};

First of all the GC::ReRegisterForFinalize in the constructor is

required because the DataTable implementation will always have GC::SuppressFinalize meaning that the MyTable destructor by default will never be called.

The above code can't compiler because the DataTable has a derived Dispose method that are marked as sealed.

If I instead of naming my method Dispose name it CleanUp then the user of MyTable could still just call Dispose (not realizing that there is a

CleanUp
method) and then the MyTable unmanaged resources are not released.

Any suggestion?

Peter



Nov 17 '05 #14

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

Similar topics

52
by: Newsnet Customer | last post by:
Hi, Statement 1: "A dynamically created local object will call it's destructor method when it goes out of scope when a procedure returms" Agree. Statement 2: "A dynamically created object...
11
by: Stub | last post by:
Please answer my questions below - thanks! 1. Why "Derived constructor" is called but "Derived destructor" not in Case 1 since object B is new'ed from Derived class? 2. Why "Derived destructor"...
2
by: | last post by:
I have this class: --------------------------------------------- class A { string a; int instances; A(); static vector<A> all; public: static A *CreateA(...................);
11
by: Ken Durden | last post by:
I am in search of a comprehensive methodology of using these two object cleanup approaches to get rid of a number of bugs, unpleasantries, and cleanup-ordering issues we currently have in our...
35
by: Peter Oliphant | last post by:
I'm programming in VS C++.NET 2005 using cli:/pure syntax. In my code I have a class derived from Form that creates an instance of one of my custom classes via gcnew and stores the pointer in a...
11
by: AB | last post by:
Hi All, I've got an array of objects, during the execution of the program I'd like to assign a particular object to a certain element in the object array. The sample code's like this... class...
23
by: Ben Voigt | last post by:
I have a POD type with a private destructor. There are a whole hierarchy of derived POD types, all meant to be freed using a public member function Destroy in the base class. I get warning C4624....
8
by: gw7rib | last post by:
I've been bitten twice now by the same bug, and so I thought I would draw it to people's attention to try to save others the problems I've had. The bug arises when you copy code from a destructor...
7
by: sam | last post by:
Hi, See when i reading a sourcecode of a program, I read that the constructor is ordinary and after that the programmer has written virtual destructor for that constructor . Why we use the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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
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...

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.