File.Open throws IOException, but file is never open/shown - c#

I am doing a simple test in code, as follows:
try
{
File.Open(path);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
path is a string declared above. This routine is called when a button is pressed, and the first time it is called, it "works normally" (in quote, because although it doesn't throw an exception, the file is never open/shown). The second time it is pressed, the following exception is thrown:
System.IO.IOException: The process cannot access the file because it is being used by another process.
However, the file is actually never open. I monitor it with Task Manager, and no instance of the file is ever exhibited.
I tried using using (File.Open(path)) {}, but to no success.
Can anybody help me? It seems like a basic mistake I'm doing, but I can't find it.
UPDATE
Lasse Vågsæther Karlsen provided the correct answer, pointing out that my mistake was actually about the concept, not the code. Thanks!

I think you've misunderstood what File.Open does.
This method will open the file for reading by your program. In other words, that method will return a Stream object which you can use to read from and write to that file.
At the end of that operation, you have to close it, which is what using would do for you.
However, I'm guessing that this is not what you want to do. You keep mentioning that the file does not open, and that you're using the Task Manager to look for the file, not seeing it.
You want Process.Start instead. You're trying to open either another executable, such as notepad.exe, or you're trying to open a document, like readme.txt, that's why you're not using the result of calling that method, and why you're using the Task Manager to look for it.
So, assuming you still want to catch exceptions, this is what you should do:
try
{
Process.Start(path);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}

Related

UnauthorizedAccessException can't be caught

I've recently run into this problem, and it doesn't make sense.
the following snippet is real:
try
{
File.Create(targetFile);
//File.WriteAllText(targetFile, $"test {DateTime.Now.ToString()}");
}
catch (UnauthorizedAccessException uaex)
{
}
I have checked it step by step, as soon as i get with the debugger to the "File.Create()" method, the exception rises, and it doesn't enter the catch block, also, if i remove the try-catch, it doesn't bubble up to the calling of the method which contains this.
Anyone got any idea why the try-catch and the bubbling doesn't work?
ps. The location where I am trying to create the file is write protected on purpose, this is just a way to check if it is.
I've made a mistake.
The exception is actually being caught, if you put anything in the catch block, it does execute.
To be fair the debugger confused me, by showing the exception pop-up right at the calling of the method, but that was solved by restarting the IDE

Log4net not logging exception

I have log4net successfully setup for my C# application. Everything works fine, except when I do this:
catch (Exception ex)
{
if (log.IsErrorEnabled)
log.Error("test", ex);
}
All I get is the message "test", I do not get the exception at all. Then, when I do this:
catch (Exception ex)
{
if (log.IsErrorEnabled)
log.Error(ex);
}
I get the exception as desired, stack trace and everything. This works, but ideally I'd like to have both the message and the exception.
Why does the exact same code (no configuration changes) not work in the first example but it does in the second example? Am I reading the docs wrong for the Error() method?
The first overload you are using is the one that you want: Error(string, Exception). If the exception is actually written depends on your appender and / or the layout you choose. Here is explained how to disable printing of the stacktrace: https://stackoverflow.com/a/3660529/106567
I need to see your configuration in order to tell why the exception is not printed.
The code that "works" is not really what you should do: log.Error(ex) seems to do what you want since log4net treats the exception as the message object and simply calls toString() on it. Any appender / layout that specifically deals with exceptions would be unable to process the exception properly. The same happens if you use one of the ErrorFormat overloads (actually I never quite understood, why you cannot use a formatted string and an exception at the same time).
The solution was not relevant in the code I posted, but I was not fixing the flags correctly. The eventual solution was already found in this stack overflow post
Try
log.ErrorFormat("test: {0}", ex);

Why does throw crash my program but return doesn't?

I am trying to catch exceptions for my form client not being able to establish a connection to a server with this in the Connect callback:
try
{
client.EndConnect(async);
}
catch (Exception e)
{
client.Close();
return;
}
This works fine but this behavior is encapsulated in to a class so I want to call throw; instead of return; so that the client class can handle it instead, like so:
try
{
client.Connect(host, port);
}
catch
{
Console.WriteLine("Could not connect to: " + host + ":" + port.ToString());
}
So why not just call throw; then? Well, for some reason if I call throw;, throw new Exception();, or basically anything other than return; the program failsfast. I'm really not sure what's causing this. I tried removing client.Close(); to see if it was the problem but nothing. If I don't call return; the program just immediately exits with no error.
Anyone know what's going on here?
Edit: I do not understand why I am getting downvoted so much. I showed how I am attempting to catch these exceptions and am asking why they are not working properly. I think the problem may be (not sure, just came up with this) because within the asynchronous callback, because it is a new thread in the ThreadPool, calling throw; does not do anything because, because it is not synchronous, there is nothing to throw back to and the application dies. Even with this knowledge, I am not sure how to solve this problem unless I put some sort of try-catch on the entire program.
I suppose a solution could be just sticking with return; because there is nothing to throw back to (due to the asynchronous callback nature of the method) and instead raise an event indicating a failure of connection. Regardless, many thanks for the downvotes and helping me solve this problem. Oh wait...
What's happening is that the EndConnect is not happening on the same thread as your BeginConnect. When EndConnect throws an exception, it is caught by the worker thread's unhandled exception handler, which fails fast (the other option is that it gets ignored and you never find out that your code isn't working).
You have to come up with a way to tell your main form thread that the connect failed.
As others have pointed out, you'll need to catch your exception one way or another to avoid program termination.
For some ideas on how you can do that "globally", see How to catch ALL exceptions/crashes in a .NET app. Whether this is actually a good idea depends on the specific needs of your program...
Relevant for WinForms:
Can't tell based on your question alone, but in case this is actually a WinForms application, you may need to be cognizant of the difference in behavior of modal forms that throw exceptions, depending on whether the debugger is active or not. Let's say we have two forms - the second one is shown as a modal child of the first one:
If application was started through debugger, second form is closed and and stack unwinding goes all the way to the first form's catch block (if any).
If application is started outside debugger, stack unwinding stops before second form is closed and generic exception message is displayed. The second form stays open and catch block in the first form is never reached.

How to handle an exception correctly

I have an xmlbuilder utility class which calls a couple of methods to build an xml file
public XMLBuilder(String searchVal)
{
this.searchVal = searchVal;
try
{
getData();
returnedData = processDataInToOriginalFormat();
WriteBasicTemplate();
}
catch (WebException)
{
//If this is thrown then there was an error processing the HTTP request for MSO data.
//In this case then i should avoid writing the xml for concordance.
serviceAvailable = false;
MessageBox.Show("Could not connect to the required Service.");
}
catch (NoDataFoundException ndfe)
{
//propegate this back up the chain to the calling class
throw;
}
processDataInToOriginalFormat(); this is a method in a class which causes an exception if the service is not available and i have propagated the exception back to here to deal with. I was going to try and set a boolean flag to indicate whether to write a certain bit of xml. If the flag is false then dont write it.
I forgot however that exceptions stop programme flow and now i realise this isnt possible as if an exception occurs the rest of the code doesn't resume. how can i get around this? just add the WriteBasicTemplate(); call in to my catch clause?
Thanks
The logic of your code is somewhat confusing and as it's not obvious what "serviceAvailable = false" will do, it's hard to give detailed tips. The general rule of excetion handling is, to catch (and not rethrow) them, if you really know what to do with them and how to fix the problem. I you don't know that or the program will be in a state where it cannot continue working, let the exception go through and let your program crash.
In your case I might structure the code like this:
try
{
returnedData = processDataInToOriginalFormat();
// put code here which should only be executed in
// case of no exception
}
catch (WebException)
{
// do what ever is required to handel the problem
MessageBox.Show("Could not connect to the required Service.");
}
// code which should be executed in every case
WriteBasicTemplate();
You shoudl also look at the "finally"-block. Depending on your requirements, you should WriteBasicTemplate in such a block. But I would probably not do so in your case. It's rather used for resource cleanup or something like that.

Displaying and capturing c# exceptions

I have a c# program which throws a NullReferenceException(). When I start this on my Vista machine, it gives the familiar screen "Foo has stopped working". I can easily click on 'details' to see what went wrong. On one XP machine there's no warning at all: the program just quits, and on another XP I get the "Foo has encountered a problem..." message. Is there a way I can change this (XP's) setting?
Furthermore, I would like to have this error message written to a log file, so I can see what went wrong if somebody else uses my program. Is there a way I can send the uncaught exceptions to a file?
edit: I want this for my entire project, not just for a critical section. I didn't think it is recommended practice to wrap the entire program in a big try...catch, or is it?
Take a look at : UnhandledException and ThreadException.
You may log the errors in a file, or use Windows logging facilities.
You may also try this and this, it should point you in the direction you want to go. It's a post about the exact same problem you are trying to solve.
If you're targeting WPF, you can use the DispatcherUnhandledException to catch any exception that you don't handle in code. Otherwise, make sure to catch any foreseeable exception with try-catch blocks.
Either in DispatcherUnhandledException's delegate or in the catch section of a try-catch block, you can then call a function that writes the error message to a log file.
Add try catch blocks around all components that you think will fail and handle these by streaming the error data to your log file
See this link:
http://blogs.msdn.com/csharpfaq/archive/2006/03/27/562555.aspx
This will get you up and running.
Use:
try
{
// Your code here
}
catch (Exception ex)
{
// This will tell you the Exception
Console.WriteLine("Exception type: {0}", ex.GetType());
// or, if you use the example from the link above
LogMessageToFile(String.Format("Exception type: {0}", ex.GetType));
}
You could wrap up your code in a
try
{
// Your code
}
catch (Exception ex)
{
streamWriter.WriteLine("your custom exception text, stack trace:" + ex.StackTrace.ToString());
MessageBox.Show("Your custom exception text, Stack Trace:" + ex.StackTrace.ToString());
}
and handle the feedback yourself with a stream writer object pointing to a log file of your chosing.
If its a winforms app you could include a message box or custom dialogue informing the user of what happened as shown above.

Categories

Resources