Estoy trabajando mucho con Visual Studio 2008 .NET C# 2.0-3.5 y Windows Forms y me he dado cuenta, al igual que muchos antes que yo, que GDI+ es extremadamente lento en la elaboración de los Controles. Nota que yo no estoy de acuerdo con imágenes (JPG, GIF, etc) mucho. Las imágenes son sólo como iconos en ciertos lugares. Esto es en realidad Controles/Formas/etc que son lentos para dibujar.

El problema es que usted puede ver los Controles de ser atraídos y puede tomar varios segundos para que un aparentemente sencillo conjunto de Controles para ser dibujado. Es decir, su quedando y horrible.

Me han hecho pruebas de donde acabo de poner un número de Etiquetas (40-50) en un formulario, apretando F5 para ejecutar y tienen que esperar a ser dibujado. De nuevo, lag y no una experiencia muy agradable.

Así, entonces no es de WPF que podría solucionar este problema, pero no estamos listos para pasar a WPF. Así que estoy buscando soluciones o correcciones y me topé con Direct2D, y al leer que algunas otras bibliotecas.

Poner Im un poco perplejo y, por lo tanto estas preguntas:

1)
Primero de todo, lo que yo quiero es una forma bastante limpia y sencilla manera de reemplazar GDI+ con algo más rápido y acelerado por hardware enfoque. Es posible hacer eso sin ir a WPF y sin tener que reescribir todo mi Windows Forms código?

Cada vez que leo algo sobre Direct2D veo cuadras de largo, generalmente horrible código de C++, me dice sobre cómo escribir código para el dibujo. Yo no quiero eso.

2)
Mientras que la lectura en la red, me topé con SlimDX, pero no puedo averiguar cómo usarlo (y lo admito, no he probado mucho, ya que de la escritura). Digamos que ya tengo una interfaz gráfica de usuario de la aplicación (Windows Forms, estándar de código de C#) – ¿puedo utilizar alguna de SlimDX (o algo parecido) a «reemplazar» GDI+ sin demasiado reescritura?

Mi problema es que no puedo encontrar ejemplos o tal decirme si es posible utilizar SlimDX, Direct2D u otros similares cosas en mi ya creado Formularios Windows forms de software, y si es posible – y cómo hacerlo.

Esperanza no estoy demasiado confuso =)

==EDITAR== 2010-09-22

He hecho algunas pruebas en mi aplicación real, y aisladas una de las cosas lentas a este:

Cuando puedo añadir texto a algunas Etiquetas en un control de usuario, los Controles de tamaño para que se ajuste al texto. Por ejemplo, los que contienen GroupControl se adapta un poco a el tamaño del texto que se acaba de agregar a la .El texto de la propiedad de las Etiquetas.

Hay alrededor de 10 controles de Etiqueta. La primera vez que las etiquetas se actualizan, y por lo tanto son los tamaños cambian, todo el proceso toma alrededor de 500 ms. La segunda vez que las etiquetas se actualizan, y no cambios de tamaño, se tarda alrededor de 0 ms.

==EDIT 2== 2010-09-22

Encuentra uno de los más despacio. A continuación, añadir una Cadena de Texto, la propiedad es lento si el texto que se agrega difiere en cadena longitud del texto que estaba allí antes de la actualización.

Estoy usando DevExpress bibliotecas, y la LabelControls se puede configurar para AutoSizeMode. Si se establece que «Ninguno», a continuación, el lag desaparece cuando la adición de texto que se diferencia en la longitud del texto anterior. Supongo que este problema va a ser el mismo de la Etiqueta normal-control, ya que también tiene un AutoSize = true/false configuración.

Sin embargo, es una «solución», pero aún demuestra mi punto es realmente lento al cambiar de tamaño, que es bastante cojo.

  • Ted, puedes publicar algunos trivial Winforms proyecto de ejemplo que muestra su problema de rendimiento?
  • Realmente te vea cómo enviar archivos aquí. Pero lo que trataba era de crear 1 Formulario, en el que el formulario I lugar 1 TabControl con 3 páginas. Cada página voy con Label, TextBox y ComboBox (200 Controles por tabPage). Entonces acabo de ejecutarlo, haga clic en/cambiar entre páginas y allí se puede ver cómo se queda. La misma cosa en condiciones normales de aplicaciones, acaba peor por lo general =(
  • estoy usando DevExpress bibliotecas – a continuación, la primera prueba para probar, es el uso estándar integrado en los Controles de Windows, a ver si son más rápidas. En mi humilde opinión, el hecho de que estás usando una librería de terceros de los controles deberá haber sido en su primer párrafo! [Ahora he añadido el correspondiente devexpress etiqueta, esperemos que hacen que sean más evidentes.]
InformationsquelleAutor Ted | 2010-09-17

5 Comentarios

  1. 2

    Muchos de los carteles de arriba vienen con buenos puntos. He creado un CAD en 3D de la aplicación en GDI+ a mí mismo, y encontré un montón lo suficientemente rápido si se implementa correctamente. El uso de Controles, sin embargo, de inmediato me parece una muy extraña manera de hacer las cosas. Un Control es bastante un objeto grande y hay muchas razones para hacer su propio en este caso.

    Te aconsejo que mire en un conserva el modo de sistema de dibujo. Es fácil de implementar y cubrir a su situación en la mayoría de los casos. Tendrías que crear la lógica del dibujo de ti mismo, pero que es divertido y le daría más flexibilidad 🙂

    • De un lado, pero tu enlace ahora redirige a un sitio del spam.
    • Parece que el chico se trasladó de la tecnología en 2014: bobpowelldotnet.blogspot.co.reino unido
    • Lamentablemente, Bob Powell murió hace unos pocos años. Su sitio era el mejor recurso en GDI+ programación de allí, y por desgracia yo no creo que haya una copia completa de su archivo en cualquier lugar.
    • Que es triste en varios niveles.
    • Afortunadamente, el Internet Archive tiene algunas copias de seguridad de su trabajo desde antes de que fuera tomado por los desalmados internet vampiros: web.archive.org/web/20120826121342/http://www.bobpowell.net/…
  2. 1

    Sobre su primera pregunta, he tenido que utilizar GDI para hacer algo de procesamiento de imagen de las cosas que estaba tomando las edades menos de GDI+. Este fue de 4-5 años y trabajar con GDI utilizando manejado C# fue un dolor – no estoy seguro de cuánto ha cambiado ahora. Hay muchos buenos y rápido a funciones tales como BitBlt que son muy rápidos en el dibujo, pero tienes que ser muy cuidadoso con la liberación de recursos (asas) y la memoria. También tuve otro problema y que estaba guardando el resultado en formato JPEG y es inexistente en GDI así que tuve que usar CxImage a leer el HBitmap y, a continuación, guárdelo.

    Todos en todos, GDI es muy rápido y robusto. Si no mejor abstracciones en DirectX, probablemente usted está mejor con ellos.

    • Thx. Bueno, yo no trato con imágenes muy mucho. Su dibujo de la normal de controles de Formularios Windows forms, bringin Formularios y entre ellos que es lento. GDI es rápido? He leído en todas partes que no es?
  3. 1

    Estoy buscando a algunos de los mismos problemas. Estoy escribiendo una aplicación que necesita para ser capaz de renderizar gráficos en 2d de manera muy eficiente, ya que algunos usuarios podrían haber 10 – 50 ventanas abiertas simultáneamente. Una cosa a considerar que nadie más habló aquí es el hecho de que direct2d sólo puede ser utilizado en equipos con windows Vista con service pack 2. Además, según este enlace:

    http://www.tomshardware.com/news/msft-windows-xp-windows-7-market-share-win7,13876.html

    El 38,5% de todos los usuarios de Windows se sigue usando XP como de Nov, 2011. Así, si la venta de la aplicación de una cantidad significativa de usuarios sigue ejecutando XP es una preocupación (o su marketbase es para países del 3er mundo que son, principalmente, el uso de XP), entonces usted debe ir con:

    1. Direct2d para nuevos sistemas operativos y GDI+ para los sistemas XP.

    2. XNA – que es compatible con XP, y también puede ser utilizado con los sistemas operativos más recientes. Ver en este enlace: http://msdn.microsoft.com/en-us/library/bb203925.aspx

    3. SlimDX – mencionado en la primera respuesta. Soporta XP así como los nuevos sistemas operativos. Ver:
      http://slimdx.org/ y http://slimdx.org/features.php

    4. OpenTK si usted se preocupa acerca de la compatibilidad entre Windows, Linux, Max, etc.

    También debe ser consciente de que había un bug con GDI+ que la hizo sufrir un muy pobre desempeño cuando fue lanzado inicialmente. Ver el siguiente enlace ¿por qué algunos desarrolladores afirman que Microsoft rompió la interfaz gráfica de usuario para Windows7 para aplicaciones utilizando GDI+:

    http://www.windows7taskforce.com/view/3607

    o hacer una búsqueda en la web a partir de su motor de búsqueda favorito con esta cadena: «gdi+ error lento en windows 7».

  4. 0

    Usted podría tratar de managed directx, pero ya no lo soporte (se trasladó a XNA). Honestamente, a menos que tengas una mierda de equipo o una tonelada de controles, yo no sé por qué se estaría quedando tan mal. Si usted está haciendo algunos cpu cosas en el hilo principal, se mueve a un subproceso independiente. Esa es la única otra razón por la que puedo pensar de que había causar ese tipo de lag.

    • Tengo un Intel 920 2.6 Ghz con 6 GB de ram, con om Win7 de 64 bits, con un montón de memoria RAM y un aburrido de la CPU. No, no es el equipo =) Un testproject de sólo addding un montón de Etiquetas, cuadros de texto en un control TabControl muestra el problema. Se queda muy visible al cambiar de pestañas (y la tabPages contienen hunders de las Etiquetas o los cuadros de texto o lo que sea)….
  5. 0

    Utilizamos SlimDX en nuestro C# app…. Pero en realidad estamos haciendo en 3D. Escribimos nuestra propia 2D lib para ser capaz de hacer simple dibujo en 2D. SlimDX es sólo una ligera envoltura alrededor de DirectX. Así que usted obtendrá todos los pro y contras de DirectX. Como que es su problema para emular la tarjeta de video, si no su presente.

    Si quieres algo para dibujo para fuera de la pantalla de mapas de bits, me gustaría ir para WPF, como es bien integrada con C#, trabaja sobre todo en todas partes, y accellerated cuando hay hardware disponible. Usted puede copiar el resultado en un mapa de bits y el uso que en GDI/Winforms. Pero sólo será más rápido que GDI+ si hacer bastante cosas complejas (un montón de filtros, una mezcla de texturas, etc…).

    Edición:

    En respuesta a los comentarios, he construido un pequeño formulario de ejemplo. Hay un segundos de tiempo de espera cuando se cambia la primera vez, pero después de que responda. Más lento de lo que yo esperaba, pero por todos los medios utilizables. Quisiera Ted comentar si esto es sobre el rendimiento que ha visto en su aplicación.

    public class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    //*** EDIT ***
    this.tabPage1.SuspendLayout();
    this.tabPage2.SuspendLayout();
    this.tabControl1.SuspendLayout();
    this.SuspendLayout();
    FillTab(tabPage1, Color.White);
    FillTab(tabPage2, Color.Yellow);
    //*** EDIT ***
    this.tabPage1.ResumeLayout(false);
    this.tabPage2.ResumeLayout(false);
    this.tabControl1.ResumeLayout(false);
    this.ResumeLayout(false);
    }
    private static void FillTab(TabPage tabPage, Color color)
    {
    for (int i = 0; i < 200; ++ i)
    {
    int left = (i % 5) * 320;
    int topOffset = (i / 5) * 23;
    tabPage.Controls.Add(new Label { Left = left, Top = topOffset, Width = 100, Text = "Label" });
    tabPage.Controls.Add(new TextBox() { BackColor = color, Left = left + 100, Top = topOffset, Width = 100, Text = tabPage.Text });
    tabPage.Controls.Add(new ComboBox { BackColor = color, Left = left + 200, Top = topOffset, Width = 100 });
    }
    }
    ///<summary>
    ///Required designer variable.
    ///</summary>
    private System.ComponentModel.IContainer components = null;
    ///<summary>
    ///Clean up any resources being used.
    ///</summary>
    ///<param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
    if (disposing && (components != null))
    {
    components.Dispose();
    }
    base.Dispose(disposing);
    }
    #region Windows Form Designer generated code
    ///<summary>
    ///Required method for Designer support - do not modify
    ///the contents of this method with the code editor.
    ///</summary>
    private void InitializeComponent()
    {
    this.tabControl1 = new System.Windows.Forms.TabControl();
    this.tabPage1 = new System.Windows.Forms.TabPage();
    this.tabPage2 = new System.Windows.Forms.TabPage();
    this.tabControl1.SuspendLayout();
    this.SuspendLayout();
    //
    //tabControl1
    //
    this.tabControl1.Controls.Add(this.tabPage1);
    this.tabControl1.Controls.Add(this.tabPage2);
    this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
    this.tabControl1.Location = new System.Drawing.Point(0, 0);
    this.tabControl1.Name = "tabControl1";
    this.tabControl1.SelectedIndex = 0;
    this.tabControl1.Size = new System.Drawing.Size(292, 266);
    this.tabControl1.TabIndex = 0;
    //
    //tabPage1
    //
    this.tabPage1.Location = new System.Drawing.Point(4, 22);
    this.tabPage1.Name = "tabPage1";
    this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
    this.tabPage1.Size = new System.Drawing.Size(284, 240);
    this.tabPage1.TabIndex = 0;
    this.tabPage1.Text = "tabPage1";
    this.tabPage1.UseVisualStyleBackColor = true;
    //
    //tabPage2
    //
    this.tabPage2.Location = new System.Drawing.Point(4, 22);
    this.tabPage2.Name = "tabPage2";
    this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
    this.tabPage2.Size = new System.Drawing.Size(245, 217);
    this.tabPage2.TabIndex = 1;
    this.tabPage2.Text = "tabPage2";
    this.tabPage2.UseVisualStyleBackColor = true;
    //
    //Form1
    //
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(292, 266);
    this.Controls.Add(this.tabControl1);
    this.Name = "Form1";
    this.Text = "Form1";
    this.tabControl1.ResumeLayout(false);
    this.ResumeLayout(false);
    }
    #endregion
    private System.Windows.Forms.TabControl tabControl1;
    private System.Windows.Forms.TabPage tabPage1;
    private System.Windows.Forms.TabPage tabPage2;
    }
    • No creo que Im siguiente. fuera de la pantalla de mapas de bits? ehm, yo sólo quiero que los controles en mi Controles/formularios para extraer de forma rápida y sin demoras. Son u diciendo que GDI+ es tan rápido se obtiene? La causa de su muy lento. He intentado añadir alrededor de 160 cuadros de texto otno un Formulario vacío, y puede que el el lag al volver a dibujar esa zona…
    • En ese caso WPF es que tal vez no sea el adecuado. Podría publicar algo de código mostrando lo que haces exaclty con esos controles? 160 vacío cuadros de texto, que es de 160 rectángulos, debe ser rápido en cualquier tecnología.
    • Hey, WPF es como ya he dicho no es una opción, ya que requeriría una gran cantidad de reescritura y eso no es una opción. El código es sencillo de un nuevo proyecto de Formularios Windows forms, 1 TabControl, que contiene cerca de 160-180 cuadros de texto. En la siguiente TabPage hay alrededor de 200-300 LabelControls y en la siguiente TabPage cerca de 200 ComboBoxes. Si luego cambia de TabPage se puede ver claramente el efecto. thx.
    • 200 cuadros de texto/comboboxes?! Estás seguro que no eres mejor usar un datagrid-tipo de control o algo? Porque me pregunta el valor de tener tantos controles en un formulario.
    • Eso no es el punto. Es sólo un ejemplo para mostrar lo lento que es. Que era sólo un proyecto de prueba. En mi normal apps que utilizan una gran cantidad de controles diferentes, y es TAN LENTO que me dan ganas de llorar.
    • Cualquier tecnología es lento si se utiliza de manera inapropiada. Ni WinForms ni WPF fueron diseñados para ese tipo de brutalidad. Usted debe agregar los controles de alguna manera, hacer uso de la virtualización, y otras técnicas similares para llevar a tamaño manejable. Por supuesto, todos estos marcos de traer algo de sobrecarga con ellos, por lo que es poco realista esperar para ser rápido en tales circunstancias. También, en uno de tus comentarios anteriores – un cuadro de texto NO es un rectángulo. Proporciona tanto la funcionalidad ni siquiera puedo encajar en este comentario. Creo que deshacer/rehacer, multi-idioma, desplazamiento, etc, etc, etc
    • Así, lo que usted está diciendo que simples Etiquetas pueden estar en forma sin ser lento. Esto se ilustra mi punto de vista con un extremadamente lento Marco. En el cuadro de texto es un control muy simple. También ver mis actualizaciones en mi pregunta anterior.
    • Ted pregunta es sobre la sustitución de la GDI pintura de controles con otra tecnología. Así que mi punto de que un cuadro de texto (un vacío) no es más el trabajo de un rectángulo, se refirió a la GDI participación, la pintura. No es seguro que un montón de sobrecarga que se encuentra aquí en alguna parte, pero dudo si GDI es el cuello de botella.
    • Comprobar el código de ejemplo he añadido si te gusta.
    • De hecho, el actual código de dibujo es casi seguro que no es el cuello de botella. Uno puede probar fácilmente que por el dibujo de las mismas cosas que el cuadro de texto dibuja – creo que hay una clase auxiliar en algún lugar en el marco que hace exactamente eso. Sorteo de 200 veces y yo no lo tendrías un problema, independientemente de la tecnología. Controles en el otro lado, son responsables de un millón de otras cosas, lo más importante del diseño de cada control tiene las alineaciones, la configuración del dock, etc, etc.
    • Gracias, voy a echar un vistazo ahora!
    • He actualizado con una Edición 2, explicando el problema que he encontrado. El problema es con el marco que es increíblemente lento cuando «redimensionar» (o lo que sea). Debe ser de esa manera.
    • Me encontré que un código de ejemplo, y sin duda la mayoría de los gal. Al cambiar entre las páginas que se acerca…. 150-200 ms? Algo así como que para la página a dibujar…
    • Si usted lee mi edición con cuidado, yo no reclamo fue instantáneo. Dado que ha cambiado la pregunta, es la pintura todavía un problema para usted?
    • Sí, la pintura sigue siendo un problema aunque es mucho mejor cuando saltarse la mitad de un segundo de tiempo de espera… =)
    • Lástima. Estás hablando de mi ejemplo, su ejemplo (que no he visto) o su código de producción? Y cuántas etiquetas/controles en cada página en su código de producción? Todavía tengo la idea de que me estoy perdiendo algo.
    • He probado tu ejemplo, y puedo ver el «lag» cuando se trata de mostrar los Controles. En mi ejemplo, hay alrededor de 200 etiquetas/comboboxes por TabPage… no ves que?
    • Sí, veo algo de retraso (y creo que ya confirmó que). Es a lo largo de las líneas de la 200ms que usted ha mencionado. Pero ese es un ejemplo con 3 veces más controles que lo que usted dice que usted necesita. Por qué no han modificado la muestra de tal manera que es casi tan complejo como lo que realmente necesita? Cuando puedo reducir el control de contar en mi muestra a 200, no es notoria demora. Así que no veo cuál es el problema.
    • Respuesta tardía. Por la sencilla razón de que quiero entender si GDI chupa o no. Es tan lento e ineficaz, que no puede dibujar 200 controles sin quedando? En mi real apps, tengo un montón de diferentes controles en todo el lugar, y de los gal. Y quiero llegar lejos de eso, si puedo.
    • Propuesta de edición: En el formulario del constructor, antes de que las llamadas a FillTab, me gustaría añadir this.tabPage1.SuspendLayout(); this.tabPage2.SuspendLayout(); this.tabControl1.SuspendLayout(); this.SuspendLayout();, a continuación, después de las llamadas añadir this.tabPage1.ResumeLayout(false); this.tabPage2.ResumeLayout(false); this.tabControl1.ResumeLayout(false); this.ResumeLayout(false);

Dejar respuesta

Please enter your comment!
Please enter your name here