Подтвердить что ты не робот

Вложенная 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))))));
    }
}

Кто-нибудь еще видел что-то подобное?

4b9b3361

Ответ 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, тесты работают нормально.