Перехват нескольких исключений в консольном приложении с помощью одного блока try{…} catch {…}

#c# #exception #console

#c# #исключение #консоль

Вопрос:

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

     static void Main(string[] args)
    {
        try
        {
            //Code which throws exceptions from time to time and runs in a loop
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        Console.ReadKey();
    }
  

Я заметил кое-что, что меня удивило. Когда генерируется исключение, код внутри блока try{…} все еще выполняется и может генерировать еще больше исключений, которые будут выведены в окно консоли.
Разве код внутри цикла не должен завершить свое выполнение и «перейти» на консоль.ReadKey() в конце?

@РЕДАКТИРОВАТЬ:

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

@EDIT2: Предположительно, это код, ответственный за поведение:

 public SomeConstructor(Socket server)
    {
        _pb = new PacketBuilder(server, c);

        SocketWrapper sw = new SocketWrapper(server, Globals.recvBufferSize);
        sw.Socket.BeginReceive(sw.Buffer, 0, Globals.recvBufferSize, SocketFlags.None,PacketReceiveCallback, sw);

        _pi = new PacketInterpreter(this, c);
    }

    private void PacketReceiveCallback(IAsyncResult iar)
    {
        SocketWrapper sw = iar.AsyncState as SocketWrapper;
        int bytesReceived = sw.Socket.EndReceive(iar);

        _pi.Interpret(sw.Buffer, 0, bytesReceived);

        if (bytesReceived > 0)
            sw.Socket.BeginReceive(sw.Buffer, 0, Globals.recvBufferSize, SocketFlags.None, PacketReceiveCallback, sw);
    }
  

Комментарии:

1. В вашем коде нет цикла. И если у вас нет внутреннего catch , он завершит попытку закрыть исключение и никогда к нему не вернется.

2. Да, так и должно быть. И вы должны предоставить код внутри блока try{…}, чтобы у нас было представление, почему он этого не делает.

3. Вероятно, у вас не должно быть блока try, который содержит так много кода, что требует комментариев, чтобы избавить нас от трудностей с его пониманием!

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

Ответ №1:

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

 static void Main(string[] args)
{
    try
    {
        //Code which throws exceptions from time to time and runs in a loop
        Console.WriteLine("Line 1");

        throw new Exception("Sample Exception"); // your code will stop here and following line will not prine.
        Console.WriteLine("This line will not print");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
    Console.ReadKey();
}
  

Ответ №2:

Единственная причина, по которой я могу предположить, почему вы получите такое поведение, — это если вы запускаете новые потоки внутри своего блока try. Итак, если вы запускаете какие-либо новые потоки или используете библиотеку task parallell или plinq, вы можете получить что-то подобное.

Но действительно сложно выполнить инспекционную отладку кода, который был заменен комментарием…