2016-01-15 2 views
1

Итак, это случилось:Исключения из Random.Next() сбой программы в блоке примерки поймать

enter image description here

Как это возможно в try -блоке? Почему это не пересылает это catch -блоку?

Edit:

Было указано, что я мог бы рекурсию. Я делаю, что, как я думал, не вызовет проблемы.

Полный метод выглядит следующим образом:

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; 
} 
+1

Это просто потому, что вы находитесь в режиме отладки. Если вы фактически запустили exe (дважды щелкнули на нем) без прикрепленного отладчика, уловка будет работать так, как ожидалось. –

+0

Посмотрите на стек вызовов в отладчике и посмотрите, что переполнено. Вероятно, вы случайно вызываете метод рекурсивно случайно. – Baldrick

+0

Скорее всего, 'ChangeLocation' является виновником, а не' Random' – Ian

ответ

0

Хорошо, было много хороших предложений. Вот сломать то, что на самом деле не так:

  • Я назвал рекурсивную функцию, которая каким-то образом сделал крах кода.
  • Я не использовал возвращаемое значение от ChangeLocation() в своем рекурсивном вызове (спасибо @leppie).
  • У было значение +3000, что означает, что это просто продолжает повторяться.
  • Random() может иметь семена для создания новой стартовой стоимости. Поскольку код работает так быстро, это то же самое число всплывает все время, что приводит к тому же значению для direction и distance. Добавление начального значения (с Sleep, как Microsoft points out) может быть решением или просто новым начальным значением.
  • Но это можно сделать более умным, так как у меня есть .

Основной причиной является то, что вызывается слишком много раз, вызывая что-то другое, чтобы выбросить исключение.

var direction = new Random(DateTime.Now.Millisecond + _recursiveCounter).Next(0, 359); 
var distance = new Random(DateTime.Now.Millisecond + _recursiveCounter).Next(0, 5); 
2

Начиная с 2.0 Exception StackOverflow можно поймать только в следующих случаях.

  1. Среда CLR запущен в размещенной среде, где хозяин специально допускает исключения StackOverflow быть обработаны
  2. StackOverflow исключение брошенную кода пользователя, а не из-за ситуации фактического переполнения стека (Reference)

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

MSDM

+0

Извините за поздний ответ - правильно, что объясняет вопрос, но не дает мне решения. Однако я думаю, что выяснил, почему это так (см. Другой ответ). –

1

Проблема

У вас есть стек переполнения исключение. Это происходит, когда используется вся память стека. Обычно это происходит, когда у вас есть рекурсивный цикл. Таким образом, метод A вызывает метод B, который вызывает метод C, который вызывает метод A, вызывающий метод B, вызывающий метод C и т. Д. И т. Д. И т. Д.

Где-то в этом цикле стек переполняется и приводит к этому исключению. Место исключения не имеет значения. В вашем случае это Random.Next(), но это также могло произойти в Console.WriteLine или где-либо еще.

StackOverflowException - особый тип исключения, который не всегда может быть использован при попытке try.

Вкратце: он не имеет отношения к Random.Next() или try-catch. Просто попробуйте найти и исправить рекурсивный цикл.

Как решить найти рекурсию

  • установить контрольную точку где-то в вашем коде разрывного.
  • Запустите приложение до тех пор, пока не ударятся о контрольных точках.
  • Продолжайте движение до тех пор, пока не наткнутся на breakpoinnt. Повторите это 3 или 4 раза.
  • Теперь проанализируйте трассировку стека и узнайте, где начинаются ваши рекурсивные циклы (какие методы повторяются) и исправить рекурсию.
+0

Я добавил редактирование оригинального сообщения. У меня есть рекурсивный звонок. Хотя я не вижу в этом проблемы ... –

+0

Это не должно быть проблемой, если это очень ясно, когда цикл должен выйти. В вашем примере я не обнаруживаю четкий выход. Возможно, 'InsidePolygon' должен сделать чек, но так как я не вижу код, я не могу его определить. –

Смежные вопросы