How to supress the creation of an (.net) Exception

2019-09-15 05:30发布

问题:

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?

回答1:

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) { }

:)



回答2:

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



回答3:

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



回答4:

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) {}


回答5:

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.



回答6:

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.



回答7:

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.



回答8:

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.