Вложенная Linq Min() сбой Visual Studio
У меня есть фрагмент кода, который делает среду разработки Visual Studio 2008 очень медленной, потребляет огромное количество памяти, а затем приводит к ее сбою. Я подозреваю, что VS поражает ограничение памяти ОС.
Следующий код не является моим реальным кодом приложения, но он имитирует проблему. По сути, я пытаюсь найти минимальное значение в дереве с помощью LINQ.
class LinqTest
{
public class test
{
public int val;
public List<test> Tests;
}
private void CrashMe()
{
test t = new test();
//Uncomment this to cause the problem
//var x = t.Tests.Min(c => c.Tests.Min(d => d.Tests.Min(e => e.Tests.Min(f=>f.Tests.Min(g=>g.Tests.Min(h => h.val))))));
}
}
Кто-нибудь еще видел что-то подобное?
Ответы
Ответ 1
Некоторое время назад я отправил отчет об ошибке в MS Connect. Сегодня утром я получил ответ:
Спасибо за отчет об ошибке для Visual Studio 2008!
Как вы отметили в своем связанном сообщении из блога Эрика Липперта, у нас есть ограничения на нашу способность делать вывод типа на таких вложенных лямбда-выражениях в разумные сроки. Тем не менее, мы могли бы, конечно, попытаться сделать так, чтобы сделать такой вывод или поставить жесткий лимит на лямбда-вложение, чтобы предотвратить этот тип проблемы. К сожалению, мы начинаем блокировать то, что мы можем исправить в Visual Studio 2010, и мы не сможем обеспечить соблюдение таких ограничений в этой версии.
Мы обязательно будем учитывать эту проблему при планировании будущих выпусков!
Алекс Тернер
Менеджер программ
Компилятор Visual С#
и
Обновлен следующий элемент обратной связи, который вы отправили в Microsoft Connect: Продукт/Технология - Visual Studio и .NET Framework - Идентификатор обратной связи - 476133 Заголовок отзыва - Вложенные Linq Min() сбой IDE Visual Studio 2008 Следующие поля или значения изменены: Состояние поля изменено с [Активный] на [Разрешено]
Разрешение поля изменилось с [Нет] на [Не будет исправлено]
Ответ 2
Я смог воспроизвести это на моей установке Visual Studio 2008. Похоже, что языковая служба попадает в бесконечный цикл и в конечном итоге исчерпывает память. Можете ли вы сообщить об ошибке на сайте подключения?
Подключиться: http://connect.microsoft.com
Если вы делаете файл с ошибкой, добавьте комментарий к моему ответу с номером ошибки.
Ответ 3
Тип вывода для вложенных лямбда-выражений занимает экспоненциальное время. Поэтому неудивительно, что компилятор замедляется, когда вы слишком много вложенности.
Тем не менее, IDE идеально подходит для таких случаев и для вывода типа прерывания, если он занимает слишком много времени.
Ответ 4
Использование базовой рекурсии вместо того, чтобы пытаться "угадать" глубину, увеличивая сложность на каждом уровне
public static class TestExt
{
public static int Min(this Test test)
{
return Math.Min(test.val, test.Tests.Min(x => x.Min()));
}
}
public class Test
{
public int val;
public List<Test> Tests;
}
public class LinqTest
{
public void GetMin()
{
Test t = new Test();
var min = t.Min();
}
}
Как отметил Райан Верса, вы также можете сделать это без дополнительных методов:
public class Test
{
public int val;
public List<Test> Tests;
public int Min()
{
return Math.Min(val,Tests.Min(x => x.Min()));
}
}
Ответ 5
Вам даже не нужно заходить так далеко. VS застыл для меня при вводе d
части вложенного выражения LINQ.
Ответ 6
Думаю, я бы отметил, что он также замораживает VS 2010, и что еще больше затормозило всю мою систему!
Ответ 7
Я думаю, что я просто испытал нечто подобное. Я просматривал свой код и использовал var
в строках, где я объявлял и инициализировал переменные new SomeClass()
. Мой код скомпилирован. Когда я попытался запустить любую Visual Studio 2008 unit test, Visual Studio сработает с CLR20r3 как имя/тип ошибки. Возвращая все мои изменения var
, тесты работают нормально.