Pregunta

Estoy trabajando en un proyecto a gran escala en la que se ha proporcionado una costumbre (bastante bueno y robusto) marco y tenemos que utilizar eso para aparecer formas y puntos de vista.


Hay StrategyEditor clase abstracta (derivado de alguna clase en marco) que se crea una instancia cada vez que se abre un nuevo StrategyForm.

StrategyForm (un marco de ventana personalizada) contiene StrategyEditor.
StrategyEditor contiene StrategyTab.
StrategyTab contiene StrategyCanvas.

Esta es una pequeña parte de las grandes clases de aclarar que hay muchos objetos que serán creados si un objeto StrategyForm se asigna en la memoria en tiempo de ejecución. Mi componente posee todas estas clases mencionadas anteriormente, excepto StrategyForm cuyo código no está en mi control.


Ahora, en tiempo de ejecución, el usuario abre muchos objetos de estrategia (que la creación de activadores del nuevo objeto StrategyForm.) Después de crear aprox. 44 objetos de estrategia, vemos que las asas objeto de usuario (utilizaré UOH de aquí en adelante) creados por los alcances de aplicación hasta alrededor de 20k +, mientras que en el registro de la cantidad predeterminada de mangos es 10k. Más información acerca de objetos de usuario aquí Testing. en diferentes máquinas dejado claro que el número de estrategia de objeto abierto es diferente para el mensaje a pop-up -. en una m / c si es 44, entonces puede ser 40 en otro

Cuando vemos el mensaje emergente, esto significa que la aplicación va a responder con lentitud. Se pone peor con unos cuantos objetos y luego la creación de marcos de ventanas y objetos posteriores fallan.

Primero pensamos que era cuestión por insuficiente memoria. Pero entonces leer más sobre new en C # ayudaron en la comprensión de que una excepción se produce si la aplicación no tiene memoria. Esto no es un problema de memoria a continuación, me siento (administrador de tareas también mostró 1,5 GB + memoria disponible.)


M / C especificaciones
Core 2 Duo a 2 GHz +
4 GB de RAM
80 GB + espacio libre en disco para el archivo de la página
juego de memoria virtual: 4000 - 6000
Mis preguntas


Q1. Se ve este como un problema de memoria y yo estoy equivocado que no es?
Q2. Hace este punto hasta el agotamiento de UOHs libres (que a mí el pensamiento) y que está dando como resultado el fracaso de la creación de identificadores de ventana?
Q3. ¿Cómo podemos evitar la carga de un objeto StrategyEditor (más allá de un umbral, manteniendo un ojo en el uso actual de UOHs)? (Que ya sabemos cómo buscar a número de UOHs en uso, así que no vayas allí.) Tenga en cuenta que la llamada a new StrategyForm() está fuera del control de mi componente.
Q4. Estoy algo confundido - ¿Cuáles son Los mangos a los objetos de usuario exactamente? MSDN está hablando de cualquier objeto que creamos o sólo algunos objetos específicos como identificadores de ventana, manijas, tiradores de cursor icono?
Q5. ¿Qué causa exactamente a utilizar hasta un LiOH? (Casi el mismo que el Q4)

Me sería muy agradecidos a todos los que me puede dar algunas respuestas informadas. ¡Muchas gracias! :)

[Actualización]
Sobre la base de la respuesta Stakx, tenga en cuenta que las ventanas que se están abriendo, estarán cerradas por sólo el usuario. Esta es una especie de MDI situación aplicación donde se abren demasiados niños ventanas. Así, Dispose no se puede llamar siempre que queramos.

¿Fue útil?

Solución

Q1

Parece que usted está tratando de crear demasiados controles de interfaz de usuario al mismo tiempo. Incluso si no hay memoria de la izquierda, que está quedando sin asas. Vea a continuación una breve, pero la explicación bastante técnico.

Q4

entiendo un objeto de usuario para ser cualquier objeto que forma parte de la interfaz gráfica de usuario. Al menos hasta que Windows XP, la interfaz de usuario de Windows API residía en USER.DLL (una de las DLL básicos que componen de Windows). Básicamente, la interfaz de usuario se compone de "ventanas". Todos los controles, como botones, cuadros de texto, casillas de verificación, son internamente la misma cosa, a saber, "ventanas". Para crearlos, que se podría llamar la función API de Win32 CreateWindow . Esa función sería entonces devuelve un recurso a la "ventana" creado (elemento de interfaz de usuario, o "objeto de usuario").

Así que supongo que a mango objeto de usuario es un identificador devuelto por esta función. (Winforms se basa en la antigua API de Win32 y por lo tanto utilizar la función CreateWindow.)

Q2

En realidad no se puede crear tantos controles de interfaz de usuario que desee. Todas las manijas del recuperados a través obligada CreateWindow en algún momento ser liberados. En Winforms, la forma más fácil y segura de hacer esto es mediante el uso del bloque using o llamando Dispose:

using (MyForm form = new MyForm())
{
    if (form.ShowDialog() == DialogResult.OK) ...
}    

Básicamente, todo System.Windows.Forms.Control puede Disposed, y debe desecharse. A veces, eso se hace de forma automática, pero no se debe confiar en él. Siempre Dispose sus controles de interfaz de usuario cuando ya no los necesita.

Nota sobre Dispose para las formas modales y no modales:

  • formas modales (mostrados con ShowDialog) son no dispuestos de forma automática. Usted tiene que hacerlo usted mismo, como se demuestra en el ejemplo código de seguridad.
  • formas modales (se muestra con Show) están dispuestos automáticamente para usted, ya que no tienen control sobre cuándo será cerrado por el usuario. No hay necesidad de Dispose explícitamente llamada!

Q5

Cada vez que se crea un objeto de interfaz de usuario, Winforms internamente realiza llamadas a CreateWindow. Eso es cómo se asignan los mangos. Y no están liberados hasta que se realice una llamada correspondiente a DestroyWindow. En Winforms, esa llamada se activa a través del método Dispose de cualquier System.Windows.Forms.Control. (Nota: Mientras estoy farily seguro sobre esto, en realidad estoy adivinando un poco Puede que no sea 100% correcto Tener un vistazo a internos Winforms usando Reflector revelaría la verdad...)

Q3

Si se asume que su StrategyEditor crea un grupo masivo de los controles de interfaz de usuario, no creo que pueda hacer mucho. Si no se puede simplificar el que el control (con respecto al número de controles secundarios que genera), entonces parece que está atrapado en la situación en la que se encuentre. Simplemente no puede crear un número infinito de los controles de interfaz de usuario.

Se podría, sin embargo, mantener un registro de cuántas StrategyEditors se abren en cualquier momento uno (incrementar un contador cada vez que uno se crea una instancia, y disminuirla cuando uno está cerrado - se puede realizar un seguimiento de este último utilizando el evento FormClosing / FormClosed de un formulario, o en el método Dispose de un control). Posteriormente, se podría limitar el número de StrategyEditors abiertos simultáneamente a un número fijo, digamos 5. Si se supera el límite, se podría producir una excepción en el constructor, por lo que no hay más casos se crean. Por supuesto que no puedo decir si StrategyForm va a manejar una excepción de su constructor StrategyEditor así ...

public class StrategyEditor : ...
{
    public StrategyEditor()
    {
        InitializeComponent();

        if (numberOfLiveInstances >= maximumAllowedLiveInstances)
            throw ...;
        // not a nice solution IMHO, but if you've no other choice...
    }
}

En cualquier caso, lo que limita el número de StrategyEditors instanciados parece como una solución temporal a mí y no va a resolver el problema real.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top