Tony said:
Hi!
What does the text below actually means ?
It's especially in the Description section below that I don't really what
they are trying to say ?
So can somebody give me some explanation what they are trying to explain.
Perhaps with a trivial example.
Best Practice
Clean up intermediate results when throwing an exception
It means to make sure that if your code catches an exception, that it
doesn't leave around the results of some incomplete operation.
This is automatically minimized to a significant extent if you are
careful to avoid writing code that has side-effects, especially not to a
large degree. Instead, make methods that return specific results,
aggregated from other methods that themselves return specific results.
Then, if in a method you catch an exception, it's easy to simply discard
whatever progress was made within the method.
Sometimes side-effects are unavoidable though. For example, it's pretty
much impossible to do any sort of file i/o without there being a
side-effect. The file itself is inherently a side-effect, in that the
operation of your own code produces effects that are observable outside
that code.
If you're reading a file, cleaning up the side-effect is easily handled
by just using the "using" statement, to ensure that streams, readers,
etc. are closed when the method is done. But if you're writing a file,
this may require somehow undoing your changes to the file. Many
applications handle this by simply not actually writing to the original
file; instead, they write to a new file, and then if the whole operation
is successful, they delete the original file and rename/move the
temporary file to the original name/location. On failure, they simply
delete the temporary file, thus cleaning up the "intermediate
result"…that is, the temporary file.
It's hard to know what "trivial example" would illustrate the issue more
clearly. But I'll try. Imagine, for example, a method that takes as
input a collection of images, and returns a new collection of
scaled-down versions of those images. If for some reason there is a
failure during the operation, you may have existing images that will not
be returned to the caller, and so which need to be disposed.
Such a method might look like this:
Image[] ScaleImages(Image[] source, Size size)
{
List<Image> result = new List<Image>();
try
{
foreach (Image image in source)
{
result.Add(new Bitmap(image, size));
}
}
catch
{
foreach (Image image in result)
{
image.Dispose();
}
throw;
}
return result.ToArray();
}
Note that if an exception is thrown (e.g. during the creation of a new
Bitmap instance), the method catches it so that it can dispose all of
the Image instances that have been created so far, since they will not
be returned to any other code that would be able to accomplish the disposal.
Pete