Click here to Skip to main content
15,886,362 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This is a long code so don't try to understand it I put it just in case
C#
static void BreakSingleGem(Gems gem)
        {
            if (output.Text != "")
            {
                if (gem is Ruby || gem is Garnet)
                {
                    if (!HasRedHearts(allUpgrades))
                        allUpgrades.Add(new RedHearts());
                }
                if (gem is Sapphire || gem is Emerald)
                {
                    if (!HasBlueHearts(allUpgrades))
                        allUpgrades.Add(new BlueHearts());
                    if (!HasGreenHearts(allUpgrades))
                        allUpgrades.Add(new GreenHearts());
                }

                foreach (Items items in allUpgrades)
                {
                    if (items.GetType() == gem.GetType() && items.Amount > 0)
                    {
                        if (items is Garnet || items is Ruby)
                        {
                            allUpgrades[0].Amount += ((Gems)items).GetRedCrystals.Amount;
                            allUpgrades[allUpgrades.Count - 1].Amount +=
                                ((Gems)items).GetRedHearts.Amount;
                            InsertRefines((Gems)items);

                            items.Amount--;
                            if (items is Garnet)
                            {
                                if (((Gems)items).GetGrade != 1)
                                    allUpgrades[((Gems)items).GetGrade * 2 - 2].Amount += 2;
                            }
                            if (items is Ruby)
                            {
                                if (((Gems)items).GetGrade != 1)
                                    allUpgrades[((Gems)items).GetGrade * 2 - 3].Amount += 2;
                            }
                            break;
                        }
                        if (items is Sapphire || items is Emerald || items is BlackOnyx)
                        {
                            if (items is Sapphire || items is BlackOnyx)
                            {
                                allUpgrades[0].Amount += ((Gems)items).GetBlueCrystals.Amount;
                                if (items is Sapphire)
                                    allUpgrades[allUpgrades.Count - 2].Amount +=
                                        ((Gems)items).GetBlueHearts.Amount;
                            }
                            if (items is Emerald || items is BlackOnyx)
                            {
                                allUpgrades[1].Amount += ((Gems)items).GetGreenCrystals.Amount;
                                if (items is Emerald)
                                    allUpgrades[allUpgrades.Count - 1].Amount +=
                                        ((Gems)items).GetGreenHearts.Amount;
                            }
                            InsertRefines((Gems)items);

                            items.Amount--;
                            if (items is Emerald || items is BlackOnyx)
                            {
                                if (((Gems)items).GetGrade != 1)
                                    allUpgrades[((Gems)items).GetGrade * 2 - 1].Amount += 2;
                            }

                            if (items is Sapphire || items is BlackOnyx)
                            {
                                if (((Gems)items).GetGrade != 1)
                                    allUpgrades[((Gems)items).GetGrade * 2 - 2].Amount += 2;
                            }
                            break;
                        }
                    }
                }
                int totalPrice = CalculateNewPrice();
                InsertToOutput(allUpgrades, totalPrice);
            }
        }


This code takes a gem and breaks it from it's components. The very weird part about it that I can't fix is the following:
When I run the code normally this process is repeated twice for some reason I can't understand. But when I put a brakepoint anywhere inside this code forcing it to pause once while doing it and forcing me to manually resume it, the code is only performed once like it should! I have no idea how to fix this... Changing the code doesn't work because it does what it should if I insert a random brakepoint but it repeats twice if I don't...
Please help me
Posted

This method is the "victim" according to your description, so the code is irrelevant for the given problem (unless there was some indirect recursion in this code - but then it presumably would always repeat twice with the same input data).

Search for all *callers* of the above mentioned method. Is it called by some GUI callback? This might disturb control flow if stopping on some breakpoints.

You may also write a stackdump as first action in this method do identify who calls it at normal execution (i.e. when executed outside the debugger).

E.g. see How to log the current call stack in .NET[^] on how to get the stack dump.

Cheers
Andi
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 26-Jul-14 21:53pm    
My 5, but "stackdump" might be not clear enough.

To add to your answer (which I credited), I added more specific advice: using "Call stack" window (please see my answer). It may appear a key for OP to solve the problem.

—SA
Andreas Gieriet 27-Jul-14 0:30am    
First of all: thank you for your 5!
Yes, if the behaviour is the same in normal execution and in the debugger, that there is no need to add the call stack dump in the code. But since the OP reports that this behaviour is only observable *without* debugger, I suggested to add the explicit stack dump in the code. The straight-forward way is of course as you suggested: show the call stack in the debugger.
Cheers
Andi
Sergey Alexandrovich Kryukov 27-Jul-14 1:18am    
Agree. Still, the "Call Stack" will never hurt. As to the "without debugger", I would put it under doubt.
—SA
In addition to Solution 1 and to your own description of your debugging effort.

Do one additional simple step: when your execution stops at the break point you described, open another debug window called "Call stack". It will show you where the call came from, up to the very top of the step. When it stops again, the stack can be different, and then compare those cases and find out the case when the call came from some method you did not expect or plan for.

—SA
 
Share this answer
 
Comments
Andreas Gieriet 27-Jul-14 0:27am    
I understand that while debugging, the call only appears once. Sounds weird to me - this is one of the (rare?) cases where the debugger disturbs normal execution too much.
I observed similar situations where the evaluation of some property causes a side effect with a history effect, where displaying the value of that property affected the status in an undesired way...
Cheers
Andi
PS: My 5 for the hint on using the debuggers call stack window.
Sergey Alexandrovich Kryukov 27-Jul-14 1:16am    
This is explainable. Many people misread the debugging results, due to some, well... emotional stress. :-) Yes, debugging can disturb the normal execution. In case of race condition, it is not even rare. I would not involve other considerations than mistakes in debugging. It should be done slower, more methodically. People often see imaginary effects because of the lack of systematic approach and just attention to the detail.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900