views:

341

answers:

7

I have a piece of code that makes the Visual Studio 2008 IDE run very slow, consume vast amounts of memory and then eventually causes it to crash. I suspect VS is hitting an OS memory limit.

The following code is not my real application code, but it simulates the problem. Essentially I am trying to find the minimum value within a tree using 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))))));
    }
}

Has anyone else seen something similar?

+3  A: 

I was able to repro this on my Visual Studio 2008 install. It looks like the language service is hitting an infinite loop and eventually running out of memory. Can you please file a bug on the connect site?

Connect: http://connect.microsoft.com

If you do file the bug, please add a comment to my answer with the bug number.

JaredPar
I am working with the original poster and have submitted the bug report under my login: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=476133
geofftnz
A: 

You don't even have to go that far. VS froze for me when typing in the d part of the nested LINQ expression.

jasonh
+3  A: 

Type inference for nested lambda expressions takes exponential time. So it's not surprising the compiler gets slow when you do too much nesting.

However, the IDE ideally would handle such cases and abort type inference if its taking too long.

Daniel
I added your link etc as a comment on the bug report. It's probably too much to ask for MS to solve an NP-Hard problem, but your timeout idea is a good one.
geofftnz
A: 

Thought i'd point out that it also freezes VS 2010, and what's more it nearly froze my whole system!

RCIX
+1  A: 

Using basic recursion instead of trying to 'guess' the depth, increasing complexity at every level

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();
    }
}

As pointed out by Ryan Versaw, you can also do this without extension methods like so:

public class Test
{
    public int val;
    public List<Test> Tests;

    public int Min()
    {
        return Math.Min(val,Tests.Min(x => x.Min()));
    }
}
Sander Rijken
This was the same solution I immediately thought of. I would point out that this extension method is only really necessary if you don't have control of your Test class (or if it's only used for testing and wouldn't make sense to have as a normal method).
Ryan Versaw
+3  A: 

A while ago I submitted a bug report on MS Connect. This morning I got a response:

Thanks for the bug report for Visual Studio 2008!

As you point out in your linked post from Eric Lippert's blog, we have limits on our ability to do type inference on such nested lambda expressions in a reasonable amount of time. That said, we could certainly try to timebox such inference or put a hard limit on lambda nesting to prevent this type of issue. Unfortunately, we're starting to lock down on what we can fix in Visual Studio 2010 and we won't be able to enforce such limits in this release.

We'll definitely keep this issue in mind when planning for future releases!

Alex Turner

Program Manager

Visual C# Compiler

and

The following feedback item you submitted at Microsoft Connect has been updated: Product/Technology - Visual Studio and .NET Framework - Feedback ID – 476133 Feedback Title – Nested Linq Min() crashes Visual Studio 2008 IDE The following fields or values changed: Field Status changed from [Active] to [Resolved]

Field Resolution changed from [None] to [Won't Fix]

geofftnz
A: 

I think I just experienced something similar. I was going through my code and using var on lines where I was declaring and initializing variables to new SomeClass(). My code compiled. When I tried to run any Visual Studio 2008 unit test, Visual Studio would crash with CLR20r3 as the error name/type. Reverting all my var changes, the tests run fine.

Sarah Vessels