2009-07-21 17 views
12

Tengo un fragmento de código que hace que el Visual Studio 2008 IDE funcione muy lento, consuma grandes cantidades de memoria y, finalmente, hace que se bloquee. Sospecho que VS está alcanzando un límite de memoria del sistema operativo.Linq Min() bloqueado Visual Studio

El siguiente código no es el código de mi aplicación real, pero simula el problema. Básicamente, estoy tratando de encontrar el valor mínimo dentro de un árbol usando 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)))))); 
    } 
} 

¿Alguien más ha visto algo similar?

Respuesta

3

Hace un tiempo presenté un bug report on MS Connect. Esta mañana recibí una respuesta:

Gracias por el informe de error para Visual Studio 2008!

Como señala en su publicación vinculada desde el blog de Eric Lippert, tenemos límites en nuestra capacidad para hacer inferencias de tipo sobre dichas expresiones lambda anidadas en un tiempo razonable. Dicho esto, sin duda podríamos tratar de hacer una inferencia de tiempo de tal tipo o poner un límite estricto a la anidación de lambda para evitar este tipo de problema. Desafortunadamente, estamos empezando a bloquear lo que podemos solucionar en Visual Studio 2010 y no podremos aplicar dichos límites en esta versión.

Definitivamente vamos a tener en cuenta este tema cuando planeemos lanzamientos futuros.

Alex Turner

Program Manager

Visual C# compilador

y

El siguiente elemento de retroalimentación que ha enviado a Microsoft Connect ha sido actualizado: Producto/Tecnología - Visual Studio and .NET Framework - ID de la retroalimentación - 476133 Título de la regeneración - Neted Linq Min() bloquea Visual Studio 200 8 IDE Los siguientes campos o valores modificados: El campo Estado cambiado [Activo] a [Resuelto] Resolución

campo cambió de [Ninguno] en [No fijará]

3

Pude reproducir esto en mi instalación de Visual Studio 2008. Parece que el servicio de idiomas está alcanzando un ciclo infinito y, finalmente, se está quedando sin memoria. ¿Puedes archivar un error en el sitio de conexión?

conexion: http://connect.microsoft.com

Si presenta el fallo, por favor dejar un comentario a mi respuesta con el número de error.

+0

Estoy trabajando con el póster original y he enviado el informe de error con mi nombre de usuario: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=476133 – geofftnz

0

Ni siquiera tiene que ir tan lejos. VS se congeló para mí al escribir en la parte d de la expresión LINQ anidada.

3

Tipo de inferencia para las expresiones lambda anidadas takes exponential time. Entonces, no es sorprendente que el compilador se vuelva lento cuando anida mucho.

Sin embargo, el IDE idealmente manejaría tales casos y abortaría la inferencia tipo si tarda demasiado.

+1

Agregué su enlace, etc. como comentario en el informe de error. Probablemente sea demasiado pedirle a MS que resuelva un problema NP-Hard, pero su idea de tiempo de espera es buena. – geofftnz

0

Pensé que señalaría que también se congela VS 2010, y lo que es más, casi congela todo mi sistema!

1

El uso de la recursividad básica en vez de intentar 'adivinar' la profundidad, complejidad cada vez mayor en todos los niveles

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

Como ha señalado Ryan Versaw, también se puede hacer esto sin los métodos de extensión de este modo:

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

    public int Min() 
    { 
     return Math.Min(val,Tests.Min(x => x.Min())); 
    } 
} 
+1

Esta fue la misma solución que pensé inmediatamente. Quiero señalar que este método de extensión solo es realmente necesario si no tienes control de tu clase de prueba (o si solo se usa para probar y no tendría sentido tenerlo como método normal). –

0

Creo que acabamos de experimentar algo similar. Estaba revisando mi código y usando var en las líneas donde estaba declarando e inicializando las variables a new SomeClass(). Mi código compilado. Cuando intenté ejecutar cualquier prueba de unidad de Visual Studio 2008, Visual Studio se bloqueaba con CLR20r3 como el nombre/tipo de error. Revertir todos mis cambios var, las pruebas funcionan bien.