Archivo de la etiqueta: C#

Cómo encontrar la versión de MSBuild que está instalada

Recientemente me ha sido necesario averiguar cual es la última versión de MSBuild que está instalada en el sistema. Hacer la comprobación de que existe un archivo en el path por defecto del tipo "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin" no es buena idea. Ya que por ejemplo puede que el usuario no lo haya instalado en ese directorio,

En StackOverflow tenéis una solución bastante interesante.

Los pasos:

  1. Instalar el paquete de Nuget Microsoft.Build.Framework.
  2. Las versiones 4.0, 12.0 y 14.0 dejan una entrada en el registro con el path:
      • Podemos consultarla
    Registry.LocalMachine.OpenSubKey($@"SOFTWARE\Microsoft\MSBuild\ToolsVersions\{msBuildVersion}")
    
  3. Para la última versión, la 15.0 hay que hacer algo más ya que esta última versión no deja huella en el registro.
    • Es necesario añadir el paquete Nuget: Microsoft.VisualStudio.Setup.Configuration.Interop
    • Y con este código es posible buscar en dónde está:
 var query = new SetupConfiguration();

        var query2 = (ISetupConfiguration2)query;

        var e = query2.EnumAllInstances();

        var helper = (ISetupHelper)query;

        int fetched;

        var instances = new ISetupInstance[1];

        do
        {
            e.Next(1, instances, out fetched);
            if (fetched > 0)
            {
                var instance = instances[0];

                var instance2 = (ISetupInstance2)instance;

                var state = instance2.GetState();

                // Skip non-complete instance, I guess?
                // Skip non-local instance, I guess?
                // Skip unregistered products?
                if (state != InstanceState.Complete
                    || (state & InstanceState.Local) != InstanceState.Local
                    || (state & InstanceState.Registered) != InstanceState.Registered)
                {
                    continue;
                }

                var msBuildComponent =
                    instance2.GetPackages()
                        .FirstOrDefault(
                            p =>
                                p.GetId()
                                    .Equals("Microsoft.Component.MSBuild",
                                        StringComparison.InvariantCultureIgnoreCase));

                if (msBuildComponent == null)
                {
                    continue;
                }

                var instanceRootDirectory = instance2.GetInstallationPath();

                var msbuildPathInInstance = Path.Combine(instanceRootDirectory, "MSBuild", msBuildVersion, "Bin", "msbuild.exe");

                if (File.Exists(msbuildPathInInstance))
                {
                    return msbuildPathInInstance;
                }
            }
        } while (fetched > 0);

Jugando con este código ya podemos ver de una forma más adecuada dónde están instaladas las versiones de MSBuild.

Espero que os sirva.

Post original en StackOverflow

 

Modificar el valor de un struct con Reflection

He estado trabajando con nuestro amigo @jacano, conocido por todos como ReflectorMan, y nos ha sido necesario modificar por reflexión el valor de una estructura (struct).

De todas las formas que encontramos de hacerlo, vimos que la más sensata es:

object boxedObject = myStruct;

….

Info.SetValue(boxedObject, structValue);

…

myStruct = (MyStruct)boxedObject;

El truco está en que al hacer el casting a object, estamos haciendo un boxing de la estructura, es decir, lo estamos convirtiendo en objecto, y podemos pasarselo al método SetValue(). Ya que todos sabemos que las estructuras se pasan por valor.

Y justo después casteamos ese objeto al tipo de la estructura para hacer el unbox y quedarnos con el valor de la estructura.

Espero que os resulte útil.

El foreach puede causar problemas de memoria

Después de tener algo de tiempo he ido a mi lista de cosas por leer y me quedado a cuadros cuando lo he leído.

http://blogs.msdn.com/b/etayrien/archive/2007/03/17/foreach-garbage-and-the-clr-profiler.aspx

Sí es un enlace del 2007, lo sé, imaginaos la de cosas que tengo en esa lista :P.

En resumen, imaginemos este código:


class Program
{
    class GameEntity
    {
        public void Update()
        {
        }
    }

    static GameEntity[] entities = new GameEntity[100];
    static Program()
    {
        for (int i = 0; i < entities.Length; i++)
        {
            entities[i] = new GameEntity();
        }
    }

    static void Main(string[] args)
    {
        byte[] byteArray = new byte[1];
        for (int i = 0; i < entities.Length; i++)
        {
            entities[i].Update();
        }
    }
}

En el post original, después de pasar el CLR Profiler no se hace reserva de memoria para un enumerador para poder recorrer la colección, algo lógico. Después, para ver la diferencia con el foreach sustituye el código del for por este otro:

static void Main(string[] args)
{
   byte[] byteArray = new byte[1];
   foreach (GameEntity e in entities)
   {
      e.Update();
   }
}

En el caso del foreach se reserva memoria para un enumerador necesario para recorrer el foreach.

Y todo va perfecto, sin embargo, hay un escenario en el que se pueden producir fugas de memoria:

const int NumEntities = 100;

static List list = new List();
static Program()
{
   for (int i = 0; i < NumEntities; i++)
   {
         list.Add(new GameEntity());
     }
}
static void Main(string[] args)
 {
     UpdateIEnumerable(list);
 }
private static void UpdateIEnumerable(IEnumerable enumerable)
 {
     foreach (GameEntity e in enumerable)
     {
         e.Update();
     }
 }

En este caso sí se producen fugas de memoria. Y es que aunque estemos haciendo un foreach en una lista, cuando se le hace un casting a una interfaz, al tipo valor del enumerador se le hace un box, y se coloca en el heap.

La conclusión:

  • Cuando hacemos un foreach sobre un Collection<T> se reserva memoria para un enumerador.
  • Cuando hacemos un foreach sobre la mayoría de las colecciones, como arrays, listas, colas, listas enlazadas y otras:
    • Si se usan explícitamente, NO se reserva memoria para un enumerador.
    • Si se usan a través de interfaces, se reserva memoria para un enumerador.

Así que si el consumo de memoria es algo crítico en vuestra aplicación o juego , nunca, nunca, uséis interfaces para recorrer una colección.

 

[Update: Gracias a Bernardo por el comentario]

El problema aparece cuando el “foreach” recorre la colección como si fuera un “IEnumerable”. En este caso se utiliza la implementación explícita de “GetEnumerator()” y se realiza “boxing” del “struct” para devolver un tipo “IEnumerator”.

El “boxing” es una operación costosa y puede llegar a consumir mucha memoria.

P.D: el método “GetEnumerator()” de  “Collection” no devuelve un “struct”. Es de las pocas colecciones que son una excepción.

Espero que os haya gustado tanto como a mi. 🙂

Juan María Laó Ramos.

CodeFluent Entities. Nunca el DDD fué tan fácil

Vamos a ver en este post es un producto que he encontrado y parece muy prometedor. CodeFluent Entities es una herramienta de modelado que nos permite generar y mantener actualizadas todas las layers y capas de nuestra aplicación. Asegurando el conjunto de buenas prácticas arquitecturales en nuestros sistemas desde su nacimiento. Esto es, han creado una herramienta para aplicar Domain Driven Development sin que apenas nos demos cuenta.

La he estado probando un tiempo y la verdad me ha dejado sorprendido, pensé en un momento que iba a ser un ORM más, pero luego descubrí el modelador de objetos de negocio, seguido de la generación de servicios RESTful, la sencillez de enlazar el modelo de negocio con las interfaces de usuario ASP.NET Web Forms, WPF y Windows Forms (están trabajando en los conectores para ASP.NET MVC, Silverlight). Sigue leyendo

¿Que significa que mi programa termine con el mensaje “This application has requested the runtime to terminate it in an unusual way”?

Estamos ejecutando nuestro programa, y de repente sale el mensaje "This application has requested Runtime to terminate in an unusual way". ¿Que ha pasado?
El mensaje lo imprime la función abort del runtime de C.
Un programa puede llamar a abort explícitamente, o puede ser llamado por el runtime.
  • La macro assert llama a abort cuando ocurre una aserción.
  • Por defecto, la función terminate llama a abort.

El estándar de C++ indica las condiciones bajo las que se llama a terminate, es una lista muy larga y no vamos a repetirla aquí. Para ver esa lista consulta tu copia favorita de estándares de C++ para verla. (la razón más común para este problema es que se ha lanzado una excepción y no se ha capturado).

Espero que sirva.
Juan María Laó Ramos.

El Señor de los Proyectos.

Durante la segunda edad del sol, los Mírdain (Altos Herreros Élficos) crearon diferentes plantillas de proyectos para Visual Studio. Estas plantillas tenían la particularidad de poseer grandes poderes imbuidos por sus creadores con el objetivo de hacer que la productividad de los desarrolladores fuera amplísima. Sin embargo los Mírdain fueron corrompidos por los Patrones de diseño, y crearon la plantilla PCL (Portable Class Library) cuyo objetivo es gobernarlos, encontrarlos, atraerlos a todos y atarlos en nuestros proyectos. Sigue leyendo

Ejecutar Test unitarios en el modo MTA (Multiple Threaded Apartment)

¿Trabajas con TDD? ¿Haces test unitarios con MSTests? ¿Tienes una máquina con varias cpus?.

Sip, parece un mundo ideal sobre todo por lo de hacer TDD, ;). Sin embargo como los TDDadores son como las meigas ... (existir no existen, pero haberlas haylas). Seguramente tendrán máquinas multicore y posiblemente haran test con Visual Studio 2010 y MSTests.

En este post veremos cómo podemos ejecutar nuestros test unitarios en el modo MTA (Multiple Threaded Apartment), lo que se conoce como hacer que se ejecuten en paralelo. Y es que el modo por defecto de su ejecución es el STA (Single threaded apartment). Sigue leyendo

Model Binding Parte 2: Filtrando datos (Serie ASP.NET vNext)

Este es el cuarto de una serie de post que estoy haciendo sobre ASP.NET vNext.

La próxima release de Visual Studio incluye un montón de nuevas características de edición de código (de las que hablaré también en el futuro). En el post de hoy veremos algunas pequeñas mejoras que incrementarán un montón la productividad con el editor de HTML a la hora de hacer las tareas más comunes.

Este post es el segundo de tres en el que hablamos sobre el nuevo soporte de Model Binding en Web Forms. Model Binding es una extensión del sistema de databinding de ASP.NET Web Forms , y ofrece un paradigma de acceso a datos centrados en el código. Hace uso de un montón de conceptos de binding que introdujimos con ASP.NET MVC - y los integra en el modelo de controles de servidor de Web Forms.

En el primer post de Model Binding vimos las bases sobre selección de datos. En el post de hoy vamos a ver cómo podemos filtrar datos previamente seleccionados basandose en la entrada de usuario, mientras mantenemos una visión de acceso a datos centrada en código. Veremos cómo podemos usar filtros con entrada de datos y valores obtenidos de un control dropdownlist. Sigue leyendo

Model Binding Parte 1: Seleccionando datos (ASP.NET vNext)

Este es el tercer post de la serie que estoy haciendo sobre ASP.NET vNext.

Las releases vNext de .NET  y Visual Studio incluyen toneladas de nuevas características y capacidades. Con ASP.NET vNext veremos un montón de mejoras tanto en Web Forms  como en MVC - y también en el núcleo sobre el que están construidos.

El post de hoy es el primero de tres post en los que hablaremos sobre el nuevo soporte de Model Binding que vendrá en Web Forms. Model Binding es una extensión del sistema de databinding de ASP.NET Web Forms , y ofrece un paradigma de acceso a datos centrados en el código. Hace uso de un montón de conceptos de binding que introdujimos con ASP.NET MVC - y los integra en el modelo de controles de servidor de Web Forms. Sigue leyendo

Smart Task y generacion de manejadores de eventos en el editor HTML (Serie ASP.NET vNext)

Este es el primero de una serie de post que voy a hacer sobre ASP.NET vNext.

La próxima release de Visual Studio incluye un montón de nuevas características de edición de código (de las que hablaré también en el futuro). En el post de hoy veremos algunas pequeñas mejoras que incrementarán un montón la productividad con el editor de HTML a la hora de hacer las tareas más comunes.

En particular, Visual Studio incluirá la opción de activar "smart tasks" en los controles de servidor de ASP.NET, y también permitirá conectar fácilmente manejadores de eventos a dichos controles - incluso sin tener que cambiar a la vista de diseño. A partir de ahora disponemos de estos escenarios también en la vista de código. Sigue leyendo

Serie sobre ASP.NET vNext

En los próximos meses trabajaré en una serie sobre las nuevas características que vendrán en las próximas versiones de ASP.NET y Visual Studio. Contienen un montón de nuevas funcionalidades y mejoras - tanto para Web Forms como para MVC - que pienso que os gustarán, y que hacen la creación de aplicaciónes más fácil, rápido y mejor.

Actualizaré esta página con enlaces a los posts individuales de la serie.

 - Smart Task y generacion de manejadores de eventos en el editor HTML (Serie ASP.NET vNext)

- Controles de datos fuertemente tipados

- Model Binding Parte 1: Seleccionando datos

Model Binding Parte 2: Filtrando datos

- Model Binding Parte 3: Actualización y validaciones.

- Nuevo soporte de Empaquetado y Minificación.

- Mejoras del editor de CSS en Visual Studio

Espero que sirva,

Scott.

Traducido por: Juan María Laó Ramos.