none
Problema con recursos en memoria en C# RRS feed

  • Pregunta

  • Buenas tardes, estoy realizando una aplicación que trabaja con imágenes y la memoria se me dispara en un determinado momento.

    La aplicación cuando va a cargar una imagen lanza un nuevo Thread, dado que el tiempo de tratar la imagen puede alargarse, y de este modo la aplicación no se queda bloqueada, si el proceso de tratamiento de imagen termina correctamente la memoria se libera sin ningún tipo de problema. El problema llega cuando se aborta de forma manual el hilo (cancelar tratar imagen) con un Thread.Abort(), por lo que he podido comprobar en la instrucción siguiente: 

    MemoryStream ms = new MemoryStream(byteImagen);

    Image img = Image.FromStream(ms); --> Aquí

    Se requiere de unas 50-100 ms de segundo dependiendo del ordenador y es cuando si en este momento el hilo principal de la aplicación aborta el hilo de tratar la imagen el Image img no libera la memoria de lo que parcialmente haya cargado.

    Hemos comprobado en el catch que no podemos hacer nada al img porque aun es igual a null porque no se le puede hacer ningun tipo de dispose() o algo parecido, también hemos intentado meterlo en la sentencia using pero cuando el abort termina el hilo tampoco hace el dispose, hemos intentado meterlo en un lock y el abort tampoco lo respeta.

    No entendemos como sin que llegue a formarse la imagen, esa memoria queda reservada y no hay forma de liberarla, ni llamando al recolector ni de ningun otro modo que conozcamos.

    ¿Que puede estar ocurriendo?

    ¿Donde va generando la imagen que le proviene del memorystream Windows que cuando no llega a terminar no la libera? 

    ¿Como podemos liberarla?

    Muchas gracias por todo.

    Un saludo,

    jueves, 12 de marzo de 2015 17:05

Respuestas

Todas las respuestas

  • A mi también me ocurre algo parecido. Espero que nos pueda ayuda alguien.
    jueves, 12 de marzo de 2015 18:03
  • Hola,

    Esto sucede porque hacer la llamada Abort no es segura y es "peligrosa" para el comportamiento de la aplicación y se espera que se hagan llamadas ante codigo no administrado, intenta marcar como unsafe la sección del código (método) que ejecutas (y donde haces el abort)

    unsafe{

    //codigo aquí

    };

    o bien, unsafe static void DoWork( .... }

    Finalmente, pueden existir muchas causas, pero por lo que comentas y la información que proporcionas suena a eso.

    Saludos,

    jueves, 12 de marzo de 2015 20:20
  • Hola,

    Esto sucede porque hacer la llamada Abort no es segura y es "peligrosa" para el comportamiento de la aplicación y se espera que se hagan llamadas ante codigo no administrado, intenta marcar como unsafe la sección del código (método) que ejecutas (y donde haces el abort)

    unsafe{

    //codigo aquí

    };

    o bien, unsafe static void DoWork( .... }

    Finalmente, pueden existir muchas causas, pero por lo que comentas y la información que proporcionas suena a eso.

    Saludos,


    Checa esta guía sobresaliente sobre Threading, saludos. http://www.albahari.com/threading/
    jueves, 12 de marzo de 2015 21:35
  • Hola,

    Esto sucede porque hacer la llamada Abort no es segura y es "peligrosa" para el comportamiento de la aplicación y se espera que se hagan llamadas ante codigo no administrado, intenta marcar como unsafe la sección del código (método) que ejecutas (y donde haces el abort)

    unsafe{

    //codigo aquí

    };

    o bien, unsafe static void DoWork( .... }

    Finalmente, pueden existir muchas causas, pero por lo que comentas y la información que proporcionas suena a eso.

    Saludos,


    Buenas, muchas gracias por tu respuesta.

    He marcado ambos métodos (donde hago el abort y el que esta ejecutando el hilo) como unsafe y aun sigue quedándose en la memoria los datos lo que hace que sobrecargue la manera si se cancelan muchas imágenes el proceso.

    Se te ocurre algo mas?

    Como podría hacer para daros mas datos?

    Un saludo,

    viernes, 13 de marzo de 2015 11:33
  • Hola,

    Encapsula tu memorystream en una instrucción using para asegurarte que una vez que dejas de usar los datos en memoria los liberes.

    using(MemoryStream stream ...

    Saludos,

    viernes, 13 de marzo de 2015 15:12