it-swarm.com.de

Was passiert, wenn eine Ausnahmebedingung im Catch-Block auftritt? Was wäre dann der Anrufer in diesem Fall

Es war eine Interviewfrage, ganz einfach, aber ich bin nicht zuversichtlich, was die Antwort angeht.

Was passiert, wenn im catch-Block eine Ausnahme auftritt? 

Ich versuche ein kleines Beispiel zu geben, was der Interviewer mich fragen wollte. Korrigieren Sie bitte mein Programm, falls es nicht kompiliert wird. Das Fazit ist, was passiert, wenn eine Ausnahme in Catch auftritt und was der Wert des Aufrufers ist.

Zum Beispiel habe ich Folgendes:

double Calculate(int x)
{
    try
    {
        x = x/2;
    }
    catch(Exception ex)
    {
        Console.Writeline("Message: "+ ex.Message);
    }
    finally
    {
      x = 10;
    }
    return x;
}

double myResult = Calculate(x); //x can be any number or 0 for example

Nun gibt es zwei Fragen:

  1. Was passiert, wenn eine Ausnahmebedingung im catch-Block auftritt? Auch, wie es zu lösen? (Dies ist ein einfaches Beispiel dafür, was der Interviewer eine ähnliche Frage stellte). 

  2. Was passiert mit myResult, wenn eine Ausnahme in der Calculate (x) -Methode auftritt? Welchen Wert hat es in allen Fällen? (Bitte erläutern Sie jeden Fall mit einem Beispiel) 

Ich möchte das auch mit einer ausführlichen Erklärung verstehen.

Ich danke dir sehr.

19
Learner

Eine Ausnahme, die in einem catch-Block ausgelöst wird, verhält sich wie eine Ausnahme, die ohne ihn ausgelöst wird - sie wird den Stapel nach oben verschieben, bis sie in einem übergeordneten catch-Block abgefangen wird, sofern vorhanden. Dies ist völlig normal, wenn Sie die ursprüngliche Ausnahme ändern oder umbrechen möchten. d.h .:

public void MyStartMethod
{
    try
    {
        //do something
        MyBadMethod();
    }
    catch(MySpecialException mse)
    {
        //this is the higher level catch block, specifically catching MySpecialException 
    }
}

public void MyBadMethod()
{
    try
    {
        //do something silly that causes an exception
    }
    catch (Exception e)
    {
        //do some logging

        throw new MySpecialException(e);
    }
}

public class MySpecialException : Exception 
{   
    public MySpecialException(Exception e) { ...etc... }
}

In Ihrem Fall hat myResult den Wert, den er zuvor hatte, auch wenn er noch im Gültigkeitsbereich ist.

23
TheEvilPenguin

Die Informationen unten helfen (von einer vorherigen Antwort von mir bis zu einer verwandten Frage). Wenn Ihr catch-Block eine Ausnahme auslöst und es keine weiteren catch-Blöcke gibt, die abgesehen von denjenigen, die ihn verursacht haben, gehandhabt werden, wird er weiterhin erneut geworfen. Anschließend wird "Windows behandelt". 

Wenn eine Ausnahme auftritt, durchläuft die CLR den Aufrufstapel und sucht nach ein passender catch-Ausdruck. Wenn die CLR keine passende findet, oder die Exception wird jedes Mal erneut ausgegeben, und die Exception sprudelt aus der Main () - Methode. In diesem Fall behandelt Windows die Ausnahme.

Die Ereignisbehandlung von Konsolenanwendungen ist am einfachsten zu verstehen weil es keine besondere Behandlung durch die CLR gibt. Die Ausnahme ist Verlassen des Applications-Threads, wenn nicht gefangen. Die CLR öffnet ein Fenster um Debuggen bitten oder die Anwendung beenden. Wenn der Benutzer sich für .__ entscheidet. debuggen, der debugger wird gestartet. Wenn der Benutzer das Schließen wählt, wird die Die Anwendung wird beendet und die Ausnahme wird serialisiert und in die .__ geschrieben. Konsole.

1
JuStDaN

Eine Ausnahme im catch verhält sich im Grunde so, als gäbe es dort keinen catch-Block zum Beginnen mit ..__ Sie sehen dieses Muster in mehrschichtigem Code, in dem Sie Ausnahmen erneut auslösen. Dies ist eine geringfügige Abweichung von Ihrem Beispiel, aber das Ergebnis ist sehr ähnlich.

try
{}
catch
{
  throw;
}

In dem obigen Fall und in Ihrem Fall wird die Ausnahme als nicht behandelt betrachtet, da sie sich immer noch im Stapel befindet. 

Es wird kein Rückgabewert angezeigt. Das Programm schlägt einfach fehl, wenn es keinen anderen Sperrblock gibt, um damit umzugehen.

1
TGH

Falls es sich um eine untergeordnete Funktion handelt, wird die Ausnahme an den catch-Block der aufrufenden Funktion gesendet.

Falls es sich um eine Hauptfunktion handelt, wird die Ausnahme ausgelöst und entweder von einer aufrufenden Methode oder von unhanded behandelt.

Zweitens schreiben wir nichts in catch-Blöcke, die eine Ausnahme verursachen können.

Sie werden normalerweise zum Auslösen oder Protokollieren von Ausnahmen verwendet.

Selbst wenn es etwas gibt, können Sie den Finally-Block verwenden, damit belegte Ressourcen freigegeben werden können. 

Ein gemeinsamer Gebrauch von catch und final zusammen ist das Erhalten und Verwenden von Ressourcen in einem try-Block, das Behandeln außergewöhnlicher Umstände in einem catch-Block und das Freigeben der Ressourcen im finally-Block.

MSDN DOKUMENTATION

1

Ich stimme mit TheEvilPenguin überein. Geben Sie einfach einen Try/Catch noch einmal in den Catch-Bereich ein. Ich habe den Code nicht ausgeführt, aber der finally-Teil wird immer ausgeführt, unabhängig davon, ob eine Ausnahme vorliegt oder nicht. Daher ist x gleich 10.

Hier ist der verrückte Code, den ich heute geschrieben habe. Wie Sie sehen, habe ich einen try/catch in den catch-Teil des Codes eingefügt:

                     if (days >= 180 || inStock == false)
                    {

                        if (mainGetSet.OrderID != MainGetSet.EMAILCANCELO)
                        {
                            if (debugging == true)
                            {
                                MessageBox.Show("Here is where support will get an email instead of it being canceled. Order ID: " + mainGetSet.OrderID);
                            }
                            string subject = "Please check order " + mainGetSet.OrderID + " to ascertain if possible cancel action is needed.";
                            string body = "Dear Support \r\n \r\nPlease check order " + mainGetSet.OrderID + " to confirm if a possible cancel action is needed " +
                            "and please process manually. Here is the SKU " + childGetSet.Sku + ". Thank you. " +
                            " \r\n \r\n Kind Regards, \r\n IT Department";
                            sendEmail.SendEmailToSupport(subject, body);

                            // Database call to the cancel order DB
                            CanceledDB.AddJSONInfo(childGetSet);

                            //readyResponse = CancelKiboOrder.MakeOrderCanceled(token, mainGetSet.OrderID);
                        }
                        MainGetSet.EMAILCANCELO = mainGetSet.OrderID;

                    }
                    else
                    {
                        if (debugging == true)
                        {
                            MessageBox.Show("Here is where support will get an email about the backorder date. Order ID: " + mainGetSet.OrderID);
                        }
                        //DateTime backorder180 = new DateTime().AddDays(days);
                        //string backOrder = backorder180.ToString("yyyy-MM-dd'T'HH:mm:ss");
                        string backOrder = DateTime.UtcNow.AddDays(days).ToString("s") + "Z";

                        string ItemsQty = string.Empty;

                        for (int iq = 0; iq < jsonGetSet.OrderItemID.Count; iq++)
                        {
                            //ItemsQty += "{  \r\n        \"autoAssign\":false,\r\n        \"locationID\":169309,\r\n        \"shipmentStatus\":\"READY\",\r\n        \"itemAssign\":[  \r\n           {  \r\n              \"orderItemID\":" + jsonGetSet.OrderItemID[iq] + ",\r\n              \"quantity\":" + jsonGetSet.Quantity[iq] + "\r\n           }\r\n        ]\r\n     }\r\n";
                            ItemsQty += "    {\r\n         \"shipmentStatus\":\"BACKORDER\",\r\n         \"backOrderReleaseDate\":\"" + backOrder + "\",\r\n         \"itemAssign\":[\r\n            {\r\n               \"orderItemID\":" + jsonGetSet.OrderItemID[iq] + ",\r\n               \"quantity\":" + jsonGetSet.Quantity[iq] + "\r\n            }\r\n         ]\r\n      }\r\n ";
                            if (jsonGetSet.OrderItemID.Count > 0 && iq < jsonGetSet.OrderItemID.Count - 1)
                            {
                                ItemsQty += ",";
                            }
                        }
                        if (debugging == true)
                        {
                            MessageBox.Show(ItemsQty);
                        }

                        string subject = "Please check backorder number " + mainGetSet.OrderID + " to ascertain  the reason.";
                        string body = "Dear Support \r\n \r\nPlease check backorder number " + mainGetSet.OrderID + " to confirm  the backorder. " +
                            "Here is the SKU " + childGetSet.Sku + "."+
                            " \r\n \r\n Kind Regards, \r\n IT Department";
                        sendEmail.SendEmailToSupport(subject, body);

                        readyResponse = Backorder.MakeOrderBackorder(token, mainGetSet.OrderID, ItemsQty);
                    }

                    if (debugging == true)
                    {
                        DebugOutput(readyResponse, textBox);
                    }

                    var parsedReady = new JObject();
                    try
                    {



                        parsedReady = JObject.Parse(readyResponse);


                    }
                    catch (Exception JEx)
                    {
                        if (debugging == true)
                        {
                            MessageBox.Show("The program threw an Exception: " + JEx);
                        }
                        else
                        { 
                            string messageSubject = "There was a problem with the JSON for the BackOrder in KIBO.";
                            string messageBody = "There was a problem with the JSON for the BackOrder in KIBO. Error: " +
                                "\r\n \r\n \r\n Here is the JSON returned: " + parsedReady;
                            string kiboSendEmail = string.Empty;

                            kiboSendEmail = sendEmail.SendEmailCS(messageSubject, messageBody, JEx);

                            if (mainGetSet.OrderID != MainGetSet.EMAILCANCELO)
                            {
                                if (debugging == true)
                                {
                                    MessageBox.Show("Here is where support will get an email instead of it being canceled. Order ID: " + mainGetSet.OrderID);
                                }
                                string subject = "Please check order " + mainGetSet.OrderID + " to ascertain if possible cancel action is needed.";
                                string body = "Dear Support \r\n \r\nPlease check order " + mainGetSet.OrderID + " to confirm if a possible cancel action is needed " +
                                "and please process manually. Here is the SKU " + childGetSet.Sku + ". Thank you. " +
                                " \r\n \r\n Kind Regards, \r\n IT Department";
                                sendEmail.SendEmailToSupport(subject, body);

                                // Database call to the cancel order DB
                                CanceledDB.AddJSONInfo(childGetSet);

                                //readyResponse = CancelKiboOrder.MakeOrderCanceled(token, mainGetSet.OrderID);
                            }
                            MainGetSet.EMAILCANCELO = mainGetSet.OrderID;


                            {
                            if (debugging == true)
                            {
                                MessageBox.Show("Here is where support will get an email about the backorder date. Order ID: " + mainGetSet.OrderID);
                            }
                            //DateTime backorder180 = new DateTime().AddDays(days);
                            //string backOrder = backorder180.ToString("yyyy-MM-dd'T'HH:mm:ss");
                            string backOrder = DateTime.UtcNow.AddDays(days).ToString("s") + "Z";

                            string ItemsQty = string.Empty;

                            for (int iq = 0; iq < jsonGetSet.OrderItemID.Count; iq++)
                            {
                                //ItemsQty += "{  \r\n        \"autoAssign\":false,\r\n        \"locationID\":169309,\r\n        \"shipmentStatus\":\"READY\",\r\n        \"itemAssign\":[  \r\n           {  \r\n              \"orderItemID\":" + jsonGetSet.OrderItemID[iq] + ",\r\n              \"quantity\":" + jsonGetSet.Quantity[iq] + "\r\n           }\r\n        ]\r\n     }\r\n";
                                ItemsQty += "    {\r\n         \"shipmentStatus\":\"BACKORDER\",\r\n         \"backOrderReleaseDate\":\"" + backOrder + "\",\r\n         \"itemAssign\":[\r\n            {\r\n               \"orderItemID\":" + jsonGetSet.OrderItemID[iq] + ",\r\n               \"quantity\":" + jsonGetSet.Quantity[iq] + "\r\n            }\r\n         ]\r\n      }\r\n ";
                                if (jsonGetSet.OrderItemID.Count > 0 && iq < jsonGetSet.OrderItemID.Count - 1)
                                {
                                    ItemsQty += ",";
                                }
                            }
                            if (debugging == true)
                            {
                                MessageBox.Show(ItemsQty);
                            }

                            string subject = "Please check backorder number " + mainGetSet.OrderID + " to ascertain  the reason.";
                            string body = "Dear Support \r\n \r\nPlease check backorder number " + mainGetSet.OrderID + " to confirm  the backorder. " +
                                "Here is the SKU " + childGetSet.Sku + "." +
                                " \r\n \r\n Kind Regards, \r\n IT Department";
                            sendEmail.SendEmailToSupport(subject, body);

                            readyResponse = Backorder.MakeOrderBackorder(token, mainGetSet.OrderID, ItemsQty);
                        }

                        if (debugging == true)
                        {
                            DebugOutput(readyResponse, textBox);
                        }

                        parsedReady = new JObject();
                        try
                        {



                            parsedReady = JObject.Parse(readyResponse);


                        }
                        catch (Exception Jx)
                        {
                            if (debugging == true)
                            {
                                MessageBox.Show("The program threw an Exception: " + Jx);
                            }
                            else
                            {
                                messageSubject = "There was a problem with the JSON for the BackOrder in KIBO.";
                                messageBody = "There was a problem with the JSON for the BackOrder in KIBO. Error: " +
                                    "\r\n \r\n \r\n Here is the JSON returned: " + parsedReady;
                                kiboSendEmail = string.Empty;

                                kiboSendEmail = sendEmail.SendEmailCS(messageSubject, messageBody, JEx);






                            }

                        }
0
Justin W

Es gibt keinen echten Rückgabewert. Die Ausnahme wird "zurückkehren".

Dies ist ein akzeptabler Code für den Compiler:

public bool fooMethod()
{
  throw new NotImplementedException();
}

In Ihrem Fall wird myResult nicht geändert.

0
Micha