开发者

Ignore Exception in C#

Is there a better way t开发者_如何学Pythono ignore an exception in C# than putting it up in a try catch block and doing nothing in catch? I find this syntax to be cumbersome. For a codeblock, can't I simply "tag" it in such a way so as runtime knows which exceptions to neglect?


I don't think there is a trick to avoid exception but you can use the following code snippet:

public void IgnoreExceptions(Action act)
{
   try
   {
      act.Invoke();
   }
   catch { }
}

Using the method looks like:

IgnoreExceptions(() => foo());

Another solution is to use AOP (Aspect Oriented Programming) - there's a tool called PostSharp which enables you to create an attribute that would catch all exceptions in specific assembly/class/method, which is closer to what you're looking for.


You can do it with AOP. Postsharp for example will allow you to easily implement such an attribute which will skip particular exceptions in methods to which you applied such an attribute. Without AOP I do not see any good way to do that (if we assume that there is a good way to do such things ;) ).

With Postsharp you will be able to decorate your methods in this way:

[IgnoreExceptions(typeof(NullReferenceException), typeof(StackOverflowException))]
void MyMethod() { ... }


One way is to take advantge of Aspect Oriented Programming (AOP). Have a look at PostSharp. Here is an example of using an exception attribute on a method so that if an exception happens, you can deal with it wihtout a try..catch block.

EDIT:

Ah yes, Dror's suggestion is also a good one. I've seen examples of that in the Enterprise Library. That would be better if you don't want to has a third party framework in your project (i.e. PostSharp).


    public static void Ignore<T>(Action a) where T : Exception
    {
        try
        {
            a();
        }
        catch (T)
        {
        }
    }

To use:

    Ignore<InvalidOperationException>(() => foo());


I don't know any mechanism that would allow you to do this.

Generally, it is also considered a very bad practice to ignore exceptions. Exceptions are (or should always be) raised for a good reason; if nothing else, you should at least log them.

If you know that a certain type of exception is not critical to your application, you can prevent it from crashing using the Application.UnhandledException event, checking for that kind of exception. Note that this will still propagate the exception through all stack frames to the very bottom.


I wanted to contribute the extension methods I created based on previous answers. Hope it helps someone.

/// <summary>
/// Extension methods for <see cref="Action"/> objects.
/// </summary>
public static class ActionExtensions
{
    /// <summary>
    /// Executes the <paramref name="action"/> and ignores any exceptions.
    /// </summary>
    /// <remarks>
    /// This should be used in very rare cases.
    /// </remarks>
    /// <param name="action">The action to execute.</param>
    public static void IgnoreExceptions(this Action action)
    {
        try { action(); }
        catch { }
    }

    /// <summary>
    /// Extends an existing <see cref="Action"/> so that it will ignore exceptions when executed.
    /// </summary>
    /// <param name="action">The action to extend.</param>
    /// <returns>A new Action that will ignore exceptions when executed.</returns>
    public static Action AddIgnoreExceptions(this Action action)
    {
        return () => action.IgnoreExceptions();
    }
}

And the unit tests:

[TestClass]
public class ActionExtensionsTests
{
    [TestMethod]
    public void IgnoreException()
    {
        Action justThrow = () => { throw new InvalidOperationException(); };
        justThrow.IgnoreExceptions();
    }
    [TestMethod]
    public void AddIgnoreException()
    {
        Action justThrow = () => { throw new InvalidOperationException(); };
        var newAction = justThrow.AddIgnoreExceptions();
        newAction();
    }
}


No. Exceptions travel back up the call stack either until they are handled by a catch block or the entire process terminates.


No. If an exception is thrown, it is usually a critical error which has happend. You do not want to ignore it.

Instead you should rewrite your code to check for the errors and only if it really fails, a exception is cast.

For example using Int32.TryParse instead of Int32.Parse to check if an object is an valid integer. Remember that exceptions are very expensive when they are cast and many casts severely affect performance of your application.


Empty catch blocks are a very stinky code smell. In short, you should not be pursuing a shorthand way of writing them.

Rule #1 is, "don't catch it if you can't handle it." Rule #1a is, "if you didn't actually handle the Exception, re-throw it."

If you're just trying to prevent the app from crashing, there are more appropriate mechanisms to use in most circumstances. .NET includes UnhandledException events at the Application, Dispatcher, and AppDomain levels, as well as events dedicated to notifying you of unhandled exceptions on background threads. At this level, if you cannot verify the state of your app, your best option may well be to notify the user something bad has happened and terminate the app.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜