используя исключения глотания блоков - PullRequest
5 голосов
/ 23 июня 2011

у меня

void foo1()
{
   using(...){...}
}

void foo2()
{
   using(...){...}
}

void foo3()
{
   using(...){...}
}

а у меня

void foo()
{
    ...
    backgroundWorker.DoWork += (s, ev) =>
                                           {
                                               try
                                               {
                                                   foo1();
                                                   foo2();
                                                   foo3();
                                               }
                                               catch (Exception ex)
                                               {
                                                   // log ex
                                               }
                                           };
      ...    
}

и я только что прочитал, что using блокирует исключения глотания. Это элегантный способ обработки исключений из foo1(), foo2() и foo3() в foo(). Я не хочу иметь попытку / перехват внутри каждого блока using в методах. Я наткнулся на этот пост , где предлагается метод расширения, но я просто проверяю, есть ли что-нибудь лучше.

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

Спасибо

Ответы [ 3 ]

3 голосов
/ 23 июня 2011

Мне кажется, я понимаю замешательство.Вот некоторый псевдокод (который может фактически выполняться?), Объясняющий ваш сценарий более просто:

public class Foo
{
    public void DoStuff()
    {
        using (var x = new Thing())
        {
            throw new ApplicationException("This code breaks");
        }
    }

    private class Thing : IDisposable
    {
        public override Dispose()
        {
            throw new ApplicationException("Help, I can't dispose!");
        }
    }
}

Этот код можно считать таким же, как этот код:

public class Foo
{
    public void DoStuff()
    {
        var x = new Thing();
        try
        {
            throw new ApplicationException("This code breaks");
            x.Dispose();
        }
        catch (Exception err)
        {
            x.Dispose();
            rethrow;
        }
    }

    private class Thing : IDisposable
    {
        public override Dispose()
        {
            throw new ApplicationException("Help, I can't dispose!");
        }
    }
}

используя блок using, вы, по сути, говорите: «Независимо от того, что вы делаете, выполните Dispose() для этого объекта, прежде чем двигаться дальше».Тем не менее, блок using не изящно обрабатывает случай, когда Dispose() не удается.Из-за этого ему никогда не удастся выбросить внутреннее исключение, потому что было еще одно исключение, которое опередило его, даже если это произошло позже.

Имеет ли это смысл?Я даже ответил на ваш вопрос?Я не уверен, если вам нужна помощь в понимании этого или чего.

1 голос
/ 23 июня 2011

Я боюсь, что Microsoft провалила здесь ту же кроличью нору, что и с WCF.

См. Как избежать проблем с оператором использования .

Может быть, они должны следовать своим собственным рекомендациям .

Практически в каждом (другом) случае using блок - это лучшая практика.

0 голосов
/ 16 марта 2013

Вы можете попробовать этот код для всплытия и исключения из оператора использования

Exception exc = null;
using (var x = new object())
{
    try
    {
       // do something x, that causes an exception to be thrown
    }
    catch(Exception ex) { exc = ex; } // bubble-up the exception
 }
 if(exc != null) { throw exc; } // throw the exception if it is not null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...