1

So, this happened:

enter image description here

How is this possible within a try-block? How come it does not forward that to the catch-block?

Edit:

It has been pointed out, that I might have recursion. I do, which I did not think would cause a problem.

The full method looks like this:

private static GeoCoordinate ChangeLocation(GeoCoordinate location)
{
    var tmp = location;
    var direction = new Random().Next(0, 359);
    var distance = new Random().Next(0, 5);

    //Calculate movement
    var vertical = Math.Sin(direction) * distance; //Sinus relation shortened
    var lastAngle = 180 - 90 - (direction % 90);
    var horisontal = Math.Sin(lastAngle) * distance; //Sinus relation shortened

    //Add movement to location
    tmp.Latitude = location.Latitude + (vertical / 10000);
    tmp.Longitude = location.Longitude + (horisontal / 10000);

    //If new location is outside a specific area
    if (!InsidePolygon(_siteCoordinates, tmp))
    {
        _recursiveCounter++;
        //Ninja edit: @Leppie pointed out I was missing 'tmp =':
        tmp = ChangeLocation(location); //Recursive move to calculate a new location
    }

    //Print the amount of recursive moves
    if (_recursiveCounter != 0)
        Console.WriteLine($"Counter: {_recursiveCounter}");
    _recursiveCounter = 0;

    return tmp;
}
Rasmus Bækgaard
  • 737
  • 2
  • 11
  • 27
  • 1
    This is just because you are in debug mode. If you actually ran the exe (double clicked on it) without any debugger attached then the catch would work as expected. – C. Knight Jan 15 '16 at 09:40
  • Take a look at your call stack in the debugger and see what's overflowing. You're probably calling a method recursively by accident somewhere. – Baldrick Jan 15 '16 at 09:40
  • Likely, `ChangeLocation` is the culprit, not the `Random` – Ian Jan 15 '16 at 09:42
  • Have you checked that ypur app actually crashes? Because your handler should simply catch the exception and your app continues. – MakePeaceGreatAgain Jan 15 '16 at 09:42
  • 2
    I believe it is more the issue, that is a StackverflowExceptions which means you can not catch it right off the bat. See: http://stackoverflow.com/a/1599236/5546740 – dryman Jan 15 '16 at 09:43
  • Obviously you are calling `ChangeLocation` within `ChangeLocation`. No (guaranteed) tail calls in C#, so just transform the recursion into a `while` loop. Edit (to reflect yours): So you do recurse, but you dont even use the return value. Something fishy... – leppie Jan 15 '16 at 09:57
  • Also, if `GeoCoordinate` is a value type, you passing `location` into it, so it will just do the same thing over and over till the stack is blown. Did you mean: `tmp = ChangeLocation(tmp);` Edit: You seem to use it like a value-type, but not sure where this type comes from. – leppie Jan 15 '16 at 10:00
  • @leppie - nicely spotted. Forgot to set ``tmp = ChangeLocation(tmp)`` – Rasmus Bækgaard Jan 15 '16 at 10:02

3 Answers3

2

Starting with 2.0 a StackOverflow Exception can only be caught in the following circumstances.

  1. The CLR is being run in a hosted environment where the host specifically allows for StackOverflow exceptions to be handled
  2. The stackoverflow exception is thrown by user code and not due to an actual stack overflow situation (Reference)

https://stackoverflow.com/a/1599238/4136669

MSDM

Community
  • 1
  • 1
Fabian S.
  • 909
  • 6
  • 20
  • Sorry for the late answer - correct, that explains the question, but does not give a me a solution. I do however think I found out why it does so (see other answer). – Rasmus Bækgaard Jan 15 '16 at 10:43
1

The problem

You have a stack overflow-exception. This happens when the all stack memory is used. This mostly happens when you have a recursive loop. So method A calls method B, which calls method C, which calls method A, calling method B, calling method C, etc. etc. etc.

Somewhere in this loop, the stack overflows and results in this exception. The place of the exception is not important. In your case it is Random.Next(), but it could also have happened in Console.WriteLine or anywhere else.

The StackOverflowException is a special type of exception which cannot always be cought by a try-catch.

In short: It has nothting to do with Random.Next() or try-catch. Just try to find and fix the recursive loop.

How to solve find a recursive loop

  • Set a breakpoint somewhere in your breaking code.
  • Run your application untill the breakpoints hits.
  • Continue till the breakpoinnt hits again. Repeat this 3 or 4 times.
  • Now analyze your stack trace and find out where your recursive loops starts (which methods are beging repeated) and fix the recursion.
Martin Mulder
  • 12,642
  • 3
  • 25
  • 54
  • I added an edit to the original post. I do have recursive call in it. Though I do not see it as a problem... – Rasmus Bækgaard Jan 15 '16 at 09:59
  • It does not have to be a problem, as long as it is very clear when the loop should exit. In your example I do not detect a clear exit. Perhaps `InsidePolygon` should do a check, but since I do not see the code, I cannot determain it. – Martin Mulder Jan 15 '16 at 12:58
0

Okay - there has been a lot of good suggestions. Here's a break down what is actually wrong:

  • I called a recursive function, which somehow made the code crash.
  • I did not use the return value from ChangeLocation() in my recursive call (thanks @leppie).
  • The _recursiveCounter had a value +3000, which means this just keeps repeating it self.
  • Random() can have a seed to generate a new start-value. Because the code runs so fast, it's the same number popping out all the time, resulting in the same value for both direction and distance. Adding a seed value (with a Sleep, as Microsoft points out) could be a solution, or just a new seed value.
  • But this can be done a tat smarter, since I have the _recursiveCounter.

The root cause is the Random().Next(...) being called too many times cause something else to throw the exception.

var direction = new Random(DateTime.Now.Millisecond + _recursiveCounter).Next(0, 359);
var distance = new Random(DateTime.Now.Millisecond + _recursiveCounter).Next(0, 5);
Rasmus Bækgaard
  • 737
  • 2
  • 11
  • 27