Hi Vinzent and ICR-
The case of the file dissappearring in the few nanoseconds between the exist check and the actual open is a extremely rare case. But it could if another process was trying to do something with that file, in that case, you would still need the try catch nad maybe have more issues with design if multiple processes were trying to access and delete the file at the same time.
Here’s a few examples of handling exceptions at the point of which they occur. With this, button1 and button2 events will not crash the program. Also, you can see the exception handling logic adds many more lines to the code as you have mentioned previously.
If my previous example was unclear, then hopefully these are better.
For handling different types of exceptions, your could modify the friendly message to see something more specific about the error, like could not find file, directory not found, etc. and store that value in a member variable or maybe a static class which stores the last error message. Catching the different types of exceptions will allow for this instead of one generic catch {}.
Let’s say I have a button on the a form and when I press it I want to open a file and process it. Here is code:
private void button1_Click(object sender, EventArgs e)
{
FileStream fs = opensomefile();
if (fs != null)
{
//Dosomething with file
//Close it after using it.
fs.Close();
}
else
{
//Alert User With Friendly Message
MessageBox.Show("Unable to open some file. Check log for details.");
//Do anything else here
}
}
/// summary
/// Opens some file and returns it back to the caller
/// /summary
/// returnsA filestream, can be null if file fails to open./returns
private FileStream opensomefile(string pathtofile)
{
FileStream fs = null;
// Open the stream
try
{
fs = File.Open(pathtofile, FileMode.Open);
}
catch (FileNotFoundException ffe)
{
//Do any specific FileNotFoundLog Logic and Log Error
}
catch (PathTooLongException ptle)
{
//Do any specific PathTooLong Logic and Log Error
}
catch (DirectoryNotFoundException dnfe)
{
//Do any specific DirectorNotFoundException Logic and Log Error
}
catch (Exception ex)
{
//Log any generic error
}
return fs;
}
Another example, lets say I have a button that going to do something specific to the file.
private void button2_Click(object sender, EventArgs e)
{
if (!dosomethingwithfile("PathToFile"))
{
//Alert User With Friendly Message
MessageBox.Show("Unable to dosomething to file. Check log for details.");
//Do anything else here
}
else
{
//Successfully processed file do any additional work here.
}
}
private bool dosomethingwithfile(string pathtofile)
{
bool success = false;
// Open the stream and do something
try
{
using (FileStream fs = File.Open(pathtofile, FileMode.Open))
{
//Do Something with FileStream
success = true;
}
}
catch (FileNotFoundException ffe)
{
//Do any specific FileNotFoundLog Logic and Log Error
}
catch (PathTooLongException ptle)
{
//Do any specific PathTooLong Logic and Log Error
}
catch (DirectoryNotFoundException dnfe)
{
//Do any specific DirectorNotFoundException Logic and Log Error
}
catch (Exception ex)
{
//Log any generic error
}
return success;
}
Both of these examples show non-bubbling of exceptions. Although trivial, I think they are valid.
You could also let exceptions bubble up if doing a multistep process, but they would not escape to other parts of program:
private bool dosomething()
{
bool success = false;
try
{
//dopart1, dopart2, dopart3, dopart4 may throw exceptions which
//will need to be caught because other callers may not handle them
//properly.
dopart1();
dopart2();
dopart3();
dopart4();
success = true;
}
catch (Exception ex)
{
//Log Error
}
return success;
}
This way you ensure that other parts of program are not responsible for any exceptions that occur in dosomething. They get a return value telling of success of failureand then may act accordingly.