Подтвердить что ты не робот

Игнорировать исключение в С#

Есть ли лучший способ игнорировать исключение в С#, чем помещать его в блок catch try и ничего не делать в catch? Я считаю, что этот синтаксис является громоздким. Для кодового блока я не могу просто "пометить" его таким образом, чтобы среда выполнения знала, какие исключения игнорируются?

4b9b3361

Ответ 1

Я не думаю, что есть трюк, чтобы избежать исключения, но вы можете использовать следующий фрагмент кода:

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

Использование метода выглядит так:

IgnoreExceptions(() => foo());

Другое решение - использовать AOP (Aspect Oriented Programming) - там есть инструмент PostSharp, который позволяет вам создать атрибут, который будет ловить все исключения в конкретной сборке/классе/методе, которые ближе к тому, что вы ищете.

Ответ 2

Вы можете сделать это с помощью АОП. Например, Postsharp позволит вам легко реализовать такой атрибут, который будет пропускать определенные исключения в методах, к которым вы применили такой атрибут. Без АОП я не вижу никакого хорошего способа сделать это (если мы предположим, что есть хороший способ сделать такие вещи;)).

С помощью Postsharp вы сможете украсить свои методы таким образом:

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

Ответ 3

Один из способов - воспользоваться преимуществами Aspect Oriented Programming (AOP). Посмотрите PostSharp. Здесь приведен пример использования атрибута исключения для метода, так что если произойдет исключение, вы можете справиться с ним с помощью блока try..catch.

EDIT:

А да, предложение Дрора тоже хорошее. Я видел примеры этого в корпоративной библиотеке. Это было бы лучше, если бы вы не хотели иметь стороннюю структуру в своем проекте (т.е. PostSharp).

Ответ 4

Я не знаю никакого механизма, который позволил бы вам это сделать.

В целом, также считается очень плохой практикой игнорировать исключения. Исключения (или всегда должны быть) подняты по уважительной причине; если ничего другого, вы должны, по крайней мере, зарегистрировать их.

Если вы знаете, что определенный тип исключения не имеет решающего значения для вашего приложения, вы можете предотвратить его сбой с помощью события Application.UnhandledException, проверяя это исключение. Обратите внимание, что это все равно будет распространять исключение через все кадры стека до самого низа.

Ответ 5

Нет. Когда происходят исключения, они перемещают резервную копию стека вызовов до тех пор, пока они не будут обработаны блоком catch или весь процесс не завершится.

Ответ 6

Нет. Если выбрано исключение, обычно это критическая ошибка, которая произошла. Вы не хотите игнорировать его.

Вместо этого вы должны переписать свой код, чтобы проверить наличие ошибок, и только если он действительно терпит неудачу, выполняется исключение.

Например, используя Int32.TryParse вместо Int32.Parse, чтобы проверить, является ли объект действительным целым числом. Помните, что исключения очень дороги, когда их отливают, и многие приведения сильно влияют на производительность вашего приложения.

Ответ 7

Пустые блоки блокировки - очень вонючий запах кода. Короче говоря, вы не должны придерживаться сокращенного способа их написания.

Правило № 1: "Не поймите, если вы не можете с этим справиться". Правило № 1а есть: "Если вы действительно не обрабатывали исключение, повторите его бросок".

Если вы просто пытаетесь предотвратить сбой приложения, в большинстве случаев есть более подходящие механизмы..NET включает события UnhandledException на уровнях Application, Dispatcher и AppDomain, а также события, посвященные уведомлению вас о необработанных исключениях из фоновых потоков. На этом уровне, если вы не можете проверить состояние своего приложения, лучшим вариантом может быть уведомление пользователя о том, что произошло что-то плохое и прекратить действие приложения.

Ответ 8

Я хотел внести вклад в методы расширения, созданные мной на основе предыдущих ответов. Надеюсь, это поможет кому-то.

/// <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();
    }
}

И модульные тесты:

[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();
    }
}

Ответ 9

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

Для использования:

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