473,405 Members | 2,272 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,405 software developers and data experts.

Delete a file in Finalizer

This is a weird problem.

1) I use MediaDet to save a bitmap in a temporary file.
2) I create a bitmap using that temporary file's name.
3) I use the bitmap.
4) I want to destroy the file when the process exits, but I am having
trouble
I have written a Finalizer on the object that actually generates the
bitmaps, as well as implementing IDisposable. The finalizer gets called, I
then call Dispose on each of the bitmaps it the object has created, and then
I call File.Delete() to delete the file used to create the bitmap.

If I call Dispose explicitly on the object in a form's Dispose method, this
works fine. If I close it in the event handler for the "Close" event, it
works fine, but if I let the garbage collector Finalize the object itself,
then this does not delete the files. It throws an IOException (which I
catch), saying that the object is in use by another process.

How can I make this object so that it cleans itself up properly? It is
going to be used by other people, so I do not want to give them too much
documentation overhead.

Richard Arthur
Nov 15 '05 #1
8 2503
Richard Arthur wrote:
This is a weird problem.

1) I use MediaDet to save a bitmap in a temporary file.
2) I create a bitmap using that temporary file's name.
3) I use the bitmap.
4) I want to destroy the file when the process exits, but I am having
trouble
I have written a Finalizer on the object that actually generates
the bitmaps, as well as implementing IDisposable. The finalizer gets
called, I then call Dispose on each of the bitmaps it the object has
created, and then I call File.Delete() to delete the file used to
create the bitmap.

If I call Dispose explicitly on the object in a form's Dispose
method, this works fine. If I close it in the event handler for the
"Close" event, it works fine, but if I let the garbage collector
Finalize the object itself, then this does not delete the files. It
throws an IOException (which I catch), saying that the object is in
use by another process.
Your problem stems from the fact that finalizers of no longer accessible
objects are called in arbitrary order. You have three objects: One of your
class, the Bitmap object and a FileStream object. As soon as the an object
of your class goes out of scope, all 3 objects become garbage. Two of these
objects have finalizers. These can be called in the correct order (finalizer
of FileStream first, finalizer of your object second) or the other way
round, which leads to the problem you're observing.
How can I make this object so that it cleans itself up properly? It
is going to be used by other people, so I do not want to give them
too much documentation overhead.


With the design you're describing there simply is no way to achieve what
you're after. You cannot reliably expose the same object (the file) to the
effects of more than one finalizer when correctness depends on their
execution order. There is a similar problem in the .NET framework with
FileStream and StreamWriter objects, both of which have finalizers. When you
forget to call Dispose() on the StreamWriter object and let it go out of
scope, data in its buffer is not written into the FileStream and is simply
lost.

If you have enough memory I would suggest to use MemoryStream instead of a
FileStream.

Regards,

Andreas

Nov 15 '05 #2
Andreas,

There is only 1 way that I can see to implement if the way you suggest.
The function that gives me the Bitmap data requests a reference to a byte.
(ref byte). I need to pass it a null for that parameter so that it will
tell me how space I need to allocate. How do I pass a null in for that
parameter? If I can do that, I can call that routine, get the size, and
then allocate a byte array that is large enough for the data. I then can
pass into that same spot a pointer to the first element in that array,
create a MemoryStream around that byte array, and then create the Bitmap.

Thanks,

Richard Arthur

is if I can pass a null into the function
"Andreas Huber" <ah****@gmx.net> wrote in message
news:40**********@news.bluewin.ch...
Richard Arthur wrote:
This is a weird problem.

1) I use MediaDet to save a bitmap in a temporary file.
2) I create a bitmap using that temporary file's name.
3) I use the bitmap.
4) I want to destroy the file when the process exits, but I am having
trouble
I have written a Finalizer on the object that actually generates
the bitmaps, as well as implementing IDisposable. The finalizer gets
called, I then call Dispose on each of the bitmaps it the object has
created, and then I call File.Delete() to delete the file used to
create the bitmap.

If I call Dispose explicitly on the object in a form's Dispose
method, this works fine. If I close it in the event handler for the
"Close" event, it works fine, but if I let the garbage collector
Finalize the object itself, then this does not delete the files. It
throws an IOException (which I catch), saying that the object is in
use by another process.
Your problem stems from the fact that finalizers of no longer accessible
objects are called in arbitrary order. You have three objects: One of your
class, the Bitmap object and a FileStream object. As soon as the an object
of your class goes out of scope, all 3 objects become garbage. Two of

these objects have finalizers. These can be called in the correct order (finalizer of FileStream first, finalizer of your object second) or the other way
round, which leads to the problem you're observing.
How can I make this object so that it cleans itself up properly? It
is going to be used by other people, so I do not want to give them
too much documentation overhead.
With the design you're describing there simply is no way to achieve what
you're after. You cannot reliably expose the same object (the file) to the
effects of more than one finalizer when correctness depends on their
execution order. There is a similar problem in the .NET framework with
FileStream and StreamWriter objects, both of which have finalizers. When

you forget to call Dispose() on the StreamWriter object and let it go out of
scope, data in its buffer is not written into the FileStream and is simply
lost.

If you have enough memory I would suggest to use MemoryStream instead of a
FileStream.

Regards,

Andreas

Nov 15 '05 #3
Richard Arthur wrote:
Andreas,

There is only 1 way that I can see to implement if the way you
suggest.
The function that gives me the Bitmap data requests a reference to a
byte. (ref byte). I need to pass it a null for that parameter so
that it will tell me how space I need to allocate. How do I pass a
null in for that parameter?


Have you tried to pass null for that parameter? I don't see any reason why
it should not work...

Regards,

Andreas

Nov 15 '05 #4
The C# compiler complains because the definition of the method says "ref
byte", and since bytes are primitive types, they cannot be null. If I could
change the way the parameter is defined, then I could pass in a null.
"Andreas Huber" <ah****@gmx.net> wrote in message
news:40**********@news.bluewin.ch...
Richard Arthur wrote:
Andreas,

There is only 1 way that I can see to implement if the way you
suggest.
The function that gives me the Bitmap data requests a reference to a
byte. (ref byte). I need to pass it a null for that parameter so
that it will tell me how space I need to allocate. How do I pass a
null in for that parameter?


Have you tried to pass null for that parameter? I don't see any reason why
it should not work...

Regards,

Andreas

Nov 15 '05 #5
"Richard Arthur" <st********@juno.com> wrote in message news:<Ox**************@TK2MSFTNGP12.phx.gbl>...
The C# compiler complains because the definition of the method says "ref
byte", and since bytes are primitive types, they cannot be null. If I could
change the way the parameter is defined, then I could pass in a null.


Sorry, I misread your previous post. I though that parameter was a ref
byte[]. What is the meaning of that parameter anyway? If there is no
other way to get at the size of the bitmap, it seems the interface is
either badly designed, badly documented or both.

Regards,

Andreas
Nov 15 '05 #6

This is the description of the method I am trying to use in the MediaDet
object. It is not documented very well.

ms-help://MS.VSCC.2003/MS.DirectX9.1033/DirectX9_c/directX/htm/getbitmapbits
methodmediaobject.htm

This is the MediaDet object in DirectX that exposes that method.

ms-help://MS.VSCC.2003/MS.DirectX9.1033/DirectX9_c/directX/htm/mediadetobjec
t.htm

ref byte is supposed to be a pointer to a byte array, but it is not exposed
very well. If the code knows the correllation between Media Types and bytes
used per pixel, and knows how much of a BitmapHeader will be tacked onto the
data, maybe the data can be allocated correctly.
"Andreas Huber" <ah****@gmx.net> wrote in message
news:3e**************************@posting.google.c om...
"Richard Arthur" <st********@juno.com> wrote in message

news:<Ox**************@TK2MSFTNGP12.phx.gbl>...
The C# compiler complains because the definition of the method says "ref
byte", and since bytes are primitive types, they cannot be null. If I could change the way the parameter is defined, then I could pass in a null.


Sorry, I misread your previous post. I though that parameter was a ref
byte[]. What is the meaning of that parameter anyway? If there is no
other way to get at the size of the bitmap, it seems the interface is
either badly designed, badly documented or both.

Regards,

Andreas

Nov 15 '05 #7
"Richard Arthur" <rb***@cs.byu.edu> wrote in message news:<u1**************@TK2MSFTNGP12.phx.gbl>...
This is the description of the method I am trying to use in the MediaDet
object. It is not documented very well.

ms-help://MS.VSCC.2003/MS.DirectX9.1033/DirectX9_c/directX/htm/getbitmapbits
methodmediaobject.htm
The docs aren't very helpful...

This is the MediaDet object in DirectX that exposes that method.

ms-help://MS.VSCC.2003/MS.DirectX9.1033/DirectX9_c/directX/htm/mediadetobjec
t.htm

ref byte is supposed to be a pointer to a byte array, but it is not exposed
very well. If the code knows the correllation between Media Types and bytes
used per pixel, and knows how much of a BitmapHeader will be tacked onto the
data, maybe the data can be allocated correctly.


Sorry, I can't help you here. The C# version of the interface seems to
be flawed. I don't see any way how you could pass in null for the
pBuffer parameter. Maybe there is a way with unsafe code.
Another way to make it work is to use a buffer that is always large
enough and copy the contents after calling the function (I assume the
function also returns the number of bytes written to the buffer).
Although this is less efficient than necessary it should be much more
efficient than the version using an external file...

Regards,

Andreas
Nov 15 '05 #8
Thanks anyway. It looks like I will just use the write-to-file method to
create the image, and then read it in. cleaning up as many of the tmeporary
files as I can, but leaving any extras there.
Richard

"Andreas Huber" <ah****@gmx.net> wrote in message
news:3e*************************@posting.google.co m...
"Richard Arthur" <rb***@cs.byu.edu> wrote in message

news:<u1**************@TK2MSFTNGP12.phx.gbl>...
This is the description of the method I am trying to use in the MediaDet
object. It is not documented very well.

ms-help://MS.VSCC.2003/MS.DirectX9.1033/DirectX9_c/directX/htm/getbitmapbits methodmediaobject.htm


The docs aren't very helpful...

This is the MediaDet object in DirectX that exposes that method.

ms-help://MS.VSCC.2003/MS.DirectX9.1033/DirectX9_c/directX/htm/mediadetobjec t.htm

ref byte is supposed to be a pointer to a byte array, but it is not exposed very well. If the code knows the correllation between Media Types and bytes used per pixel, and knows how much of a BitmapHeader will be tacked onto the data, maybe the data can be allocated correctly.


Sorry, I can't help you here. The C# version of the interface seems to
be flawed. I don't see any way how you could pass in null for the
pBuffer parameter. Maybe there is a way with unsafe code.
Another way to make it work is to use a buffer that is always large
enough and copy the contents after calling the function (I assume the
function also returns the number of bytes written to the buffer).
Although this is less efficient than necessary it should be much more
efficient than the version using an external file...

Regards,

Andreas

Nov 15 '05 #9

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

Similar topics

5
by: jim | last post by:
Why was a destructor (finalizer) included in the syntax of C# if implementing IDisposable is the sure way to release resources held by a class? If you were doing a language from scratch would you...
3
by: esafran | last post by:
I've defined a class, but now I want to Define a Finalizer (destructor)... How do I call the Base Finalizer???, void Finalize() is a protected override method and Type.GetType Does not work. ...
7
by: Shanli RICHEZ | last post by:
I'm using ASP.NET and quite a lot of object in memory instead of a database. The question is that I tried to save the data, serialize them in a XML file to save them when the application is...
21
by: ajbecker | last post by:
I'm trying to debug a problem I'm having where my finalizer queue is getting filled up faster than the thread can execute them, (or at least I think that's what's going on.) Is there a way that I...
4
by: Zen | last post by:
Hi, Is my finalizer safe? Thanks!! public class MyClass { private string m_str; public MyClass( string s ) {
5
by: tstephan | last post by:
I remember reading a few years back about destructors not being guarenteed to be run. Doing a search all I can find is a reference to some bugs with finalizers and appdomains in 1.0 and 1.1. Are...
6
by: Sharon | last post by:
When an object is register to event (delegate marked as event) with one of its methods, what happen when the event is raised if the object is dead (finalized)? In this case the delegate invocation...
15
by: Zytan | last post by:
I have installed the Visual C# 2005 Code Snippets, and the snippets for file handling use StreamReader and StreamWriter, instead of System.IO.File.*. VB 2005 code snippets don't use these. Why...
3
by: =?Utf-8?B?VHJlY2l1cw==?= | last post by:
Hello, Newsgroupians: I've created a class that wraps DbConnection. public class CSQL { protected System.Data.Common.DbConnection m_conn; public CSQL {
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
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
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
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
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
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.