views:

183

answers:

8

Hi there,

If I do not care about a thrown Exception. Can I code in a way as not to create it?

In other words, can an Exception be thrown but no Exception object be created?

An example - Simple example using a System.Net.Sockets.Socket

 Socket acceptingSocket;
acceptingSocket.Blocking = false;

while(condition)
{
    try
    {
        Socket acceptedSocket = acceptingSocket.Accept(); //(i)
        doWork(acceptedSocket);
    }
    catch{}
}

because the socket is in non-blocking mode if there is no connection to accept a SocketException is thrown at point (i) and the conditional loop continues.

using this code implementation - will the SocketException object be created?

AND if it is created - is there a way to NOT create it?

+3  A: 

Yes, it will be created. No, there is no way to avoid this.

Sander
+2  A: 

It will always be created. AFAIK there is no way to prevent the exception object being created...

Ali Shafai
+2  A: 

An Exception object is always created when throwing an exception. All you are doing is specifying that you do not care what type the exception is and that you don't need to reference it. doWork will not be called if an exception is thrown by acceptingSocket.Accept.

Your code is equivalent to:

catch(Exception) {}
Richard Szalay
I don't think it is - a naked catch statement will catch some non-CLR exceptions thrown by native code, whereas catch(Exception) will only catch CLR exceptions.
Simon
Good point, though my main point was that the creation of the exception object cannot be prevented.
Richard Szalay
+2  A: 

You can't suppress exceptions, you can only ignore them. In any case, it's not the creating of the Exception object that's expensive -- it's the stack walk that happens when the exception is thrown.

Also,

catch(SocketException) {}

not

catch { } or catch(Exception) { }

:)

Rytmis
A: 

It's already pointed out that you can't prevent it, but I'd like to point out why. The code you'r calling is likely written before your code. And when it was written, the cases in which an exception are thrown were already established. Nothing you can do in your code can go back in time and change the decisions made by the developers of the callee.

Note that a smart Virtual Machine may be able to eliminate the exception when JITting. Unlike you and the other developers, it sees both sides combined and can make smart decisions based on the combination. The x86 exception model doesn't match the .Net exception model anyway, so the VM already has to perform a smart mapping. E.g. in this case it might get away by return a nullpointer instead - your code wouldn't notice.

MSalters
A: 

Unless your code or environment is really screwed up dont worry about the performance cost of the occassional exception here and there. Exceptions happen all the time inside the runtime and its not a big deal. Of course if you end up doing crazy stuff like walking past the end of arrays so you can skip testing against the array length this will hurt if your method is frequently called.

Try and do your best to avoid throwing / causing them unnecessarily.

mP
+2  A: 

This is unrelated but important, I think.

Why is your socket in non-blocking mode inside a loop? If the socket has no incoming connection, you'd just enter the loop again indefinitely until there is such a connection. What you are doing here is busy waiting, and it will take a lot of CPU power - the exception being created really shouldn't worry you here.

configurator
@configurator - I want to be able to easily stop/start/stop accepting connections. This is not possible if a thread is blocked while waiting for an Accept(). My code does utilise the Socket.Poll() and other methods before calling Accept() so as not to throw the SocketExceptions. HOWEVER you are right it is 'busy waiting'. Im I right in presuming that if I used a blocking socket - the socket would just be 'busy waiting' for a connection at a lower level?
divinci
No, you are wrong. The socket would not be busy waiting, but would be *actually* waiting. That means that the thread will not take up cpu and will not be alloted time until the underlying semaphore (or mutex or whatever) is released. You can break the thread by other means. Perhaps if you add a timeout, say 500 ms, it would only restart the wait twice a second, and it could be quickly stopped.
configurator
@configurator - Thanks for the timeout suggestion, it will be implemented :)
divinci
A: 

As has been previously mentioned, if an exception is caught and ignored, then it was created and thrown. There is no way to suppress the creation and throw of an exception when an exceptional case has already occurred, however, there are often things you can do to prevent the exceptional case.

In your case, your using a Socket. There are many possible reasons why a SocketException may be thrown...such as trying to read from a closed socket. To prevent the exception from being thrown, you would want to verify that the socket is still open before initiating a read. This will incur the added cost of checking the sockets state before each read, but in the long run, you could likely perform thousands of such checks before you reach the level of overhead that reading from a closed socket and throwing an exception would incur.

In general, performing such checks is just good programming practice. We should be writing code that avoids exceptional cases as much as possible. A classic example of this is checking parameters and other variables for null before accessing methods or properties on them, which avoids the dreaded NullReferenceException (an exception that, in a properly written application, should NEVER be thrown.)

It takes a little time and experience to always be aware of the possible exceptional cases in your code, but if you try to have the presence of mind to think about it, you'll be able to avoid exceptions in most cases by validating your input, recieved data, etc. before using it in a way that will cause an exception.

jrista
@jrista - thanks for your suggestions and guidance - I am just learning c# - and this weekend I will be looking at testing - if I wanted to test that your statement of<br/><br/><b>"This will incur the added cost of checking the sockets state before each read, but in the long run, you could likely perform thousands of such checks before you reach the level of overhead that reading from a closed socket and throwing an exception would incur."</b><br/><br/>how would I go about it?
divinci