web-dev-qa-db-fra.com

Que se passe-t-il si une exception se produit dans le bloc Catch en C #? Aussi, quel serait le résultat de l'appelant dans ce cas

C'était une question d'entrevue, assez simple, mais je ne suis pas confiant quant à la réponse.

Que se passe-t-il si une exception se produit dans le bloc catch? 

J'essaie de donner un exemple petit prog de ce que l'intervieweur essayait de me demander, corrigez s'il vous plaît mon programme s'il ne compile pas, je suis vraiment nouveau dans ce domaine. La ligne du bas est ce qui se passe si une exception se produit dans Catch et quelle sera la valeur de l'appelant au cas par cas.

Par exemple, j'ai les éléments suivants:

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

Maintenant, il y a deux questions:

  1. Que se passe-t-il si une exception se produit dans le bloc catch? Aussi, comment le résoudre? (Ceci est un exemple simple de ce que l'intervieweur posait une question similaire). 

  2. Qu'adviendra-t-il de myResult si une exception se produit dans la méthode Calculate (x)? Quelle sera sa valeur dans tous les cas? (Veuillez expliquer chaque cas avec un exemple) 

Je voudrais comprendre cela avec une explication détaillée aussi.

Merci beaucoup.

19
Learner

Une exception levée dans un bloc catch se comportera comme une exception levée sans elle: elle remontera dans la pile jusqu'à ce qu'elle soit capturée dans un bloc d'interception de niveau supérieur, le cas échéant. Cela est tout à fait normal si vous souhaitez modifier ou envelopper l'exception d'origine. c'est à dire.:

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... }
}

Dans votre cas, myResult aura la valeur qu'il avait auparavant, si elle est encore dans la portée.

23
TheEvilPenguin

L'information ci-dessous vous aidera (d'une réponse précédente à une question connexe). Si votre bloc catch lève une exception et qu'il n'y a pas d'autre bloc catch pour le gérer, hormis celui qui l'a provoqué, il continuera à être renvoyé, puis «Windows le traitera». 

Si une exception se produit, le CLR traverse la pile d'appels à la recherche de une expression de capture correspondante. Si le CLR ne trouve pas celui qui correspond, ou l’exception est renvoyée à chaque fois, l’exception bouillonne de la méthode Main (). Dans ce cas, Windows gère l'exception.

La gestion des événements des applications de console est la plus simple à comprendre, car il n'y a pas de traitement spécial par le CLR. L'exception est laissant le fil d'applications si non attrapé. Le CLR ouvre une fenêtre demander le débogage ou quitter l'application. Si l'utilisateur choisit de déboguer, le débogueur démarre. Si l'utilisateur choisit de fermer, le fichier L'application se ferme et l'exception est sérialisée et écrite dans le fichier console.

1
JuStDaN

Une exception dans la capture se comportera essentiellement comme s'il n'y avait pas de bloc de capture pour commencer avec . Vous voyez ce modèle dans du code multicouche où vous reniflez des exceptions. Ceci est une légère variation de votre exemple, mais le résultat est très similaire.

try
{}
catch
{
  throw;
}

Dans le cas ci-dessus et dans votre cas, l'exception est considérée comme non gérée, car elle se propage toujours dans la pile. 

Il n'y aura pas de valeur de retour. Le programme échoue simplement s'il n'y a pas d'autre blocage pour y faire face.

1
TGH

Dans le cas où sa fonction est enfant, l'exception sera envoyée au bloc catch de la fonction appelante

Dans le cas où il s'agirait d'une fonction principale, l'exception serait levée et gérée par une méthode appelante ou sans traitement

Deuxièmement, nous n'écrivons rien dans les blocs catch qui puisse provoquer une exception.

Ils sont généralement utilisés pour lancer ou enregistrer une exception.

Même s'il y a quelque chose, vous pouvez utiliser le bloc Finally afin que toutes les ressources occupées puissent être relâchées. 

Une utilisation courante de catch et de la combinaison consiste à obtenir et à utiliser des ressources dans un bloc try, à gérer des circonstances exceptionnelles dans un bloc catch et à libérer les ressources du bloc finally.

DOCUMENTATION MSDN

1
Vinay Pratap Singh

Je suis d'accord avec TheEvilPenguin. Il suffit de mettre un essai/attraper une fois de plus dans la partie attrape. Je n'ai pas exécuté le code, mais la partie finale sera toujours exécutée, qu'il y ait une exception ou non, donc x est égal à 10.

Voici le code fou que j'ai écrit aujourd'hui. Comme vous pouvez le constater, je mets try/catch dans la partie catch du code:

                     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

Il n'y a pas de valeur de retour réelle. L'exception "retournera".

C'est un code acceptable pour le compilateur:

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

Dans votre cas, myResult ne sera pas changé.

0
Micha