A
Amit
Hello,
I just ran into a weird problem with FileStream. The problem occurs in
the following scenario:
- I create an instance of FileStream and use it to write to a disk
which have just a small amount of free space.
- When the disk gets full, FileStream throws an IOException. I catch
and process it.
- My program continues executing. At some later point, I'm getting an
unhandled IOException (althoug the whole code is wrapped in try-catch
block).
- After inspecting the call stack and the running threads I made the
following observations:
--- The second exception occurs in a thread which doesn't belong to my
process.
--- The call stack of the thread in which this exception occurs starts
within the FileStream finalize method.
By observing the calls in the call stack, I believe that what happen
is as follows:
When the disk gets full and the first exception (that I handle)
occurs, the buffer of the FileStream object is not empty. However,
since the object gets out of scope, the garbage collector tries to
release it at some point. The garbage collector calls finalize, which
calls dispose, and one of the calls in this sequense is a call to
flush() that tries to write the buffer before killing the object.
Since the disk is full, this call fails and an IOException is thrown
from the garbage collector thread.
I found no way to get around this, except from disabling garbage
collection for the FileStream object, which IMHO is pretty ugly. If the
garbage collector and FileStream always work in this way, i.e. the GC
calls finalize, which causes flush to be called without knowing that
the disk is already full and a previous write failed, then it seems
like a bug in the framework.
I would appreciate any comments,
TIA,
Amit
P.s. Below is the code I've been using for demonstrating this problem:
static void Main(string[] args)
{
try
{
FileStream fs =
new FileStream(args[0], FileMode.Create);
Console.WriteLine("starting to write...");
while (true)
fs.WriteByte(0xff);
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}",
e.Message);
}
Console.WriteLine("press any key to continue");
Console.Read();
}
I just ran into a weird problem with FileStream. The problem occurs in
the following scenario:
- I create an instance of FileStream and use it to write to a disk
which have just a small amount of free space.
- When the disk gets full, FileStream throws an IOException. I catch
and process it.
- My program continues executing. At some later point, I'm getting an
unhandled IOException (althoug the whole code is wrapped in try-catch
block).
- After inspecting the call stack and the running threads I made the
following observations:
--- The second exception occurs in a thread which doesn't belong to my
process.
--- The call stack of the thread in which this exception occurs starts
within the FileStream finalize method.
By observing the calls in the call stack, I believe that what happen
is as follows:
When the disk gets full and the first exception (that I handle)
occurs, the buffer of the FileStream object is not empty. However,
since the object gets out of scope, the garbage collector tries to
release it at some point. The garbage collector calls finalize, which
calls dispose, and one of the calls in this sequense is a call to
flush() that tries to write the buffer before killing the object.
Since the disk is full, this call fails and an IOException is thrown
from the garbage collector thread.
I found no way to get around this, except from disabling garbage
collection for the FileStream object, which IMHO is pretty ugly. If the
garbage collector and FileStream always work in this way, i.e. the GC
calls finalize, which causes flush to be called without knowing that
the disk is already full and a previous write failed, then it seems
like a bug in the framework.
I would appreciate any comments,
TIA,
Amit
P.s. Below is the code I've been using for demonstrating this problem:
static void Main(string[] args)
{
try
{
FileStream fs =
new FileStream(args[0], FileMode.Create);
Console.WriteLine("starting to write...");
while (true)
fs.WriteByte(0xff);
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}",
e.Message);
}
Console.WriteLine("press any key to continue");
Console.Read();
}