2013-09-07 10 views
13

Die RichEditBox Kontrolle in C# (ich benutze VS 2005) hat schlechte Leistung. Ich lade eine RTF-Datei von 2,5 MB mit 45.000 farbigen Zeilen Text in das Steuerelement und es dauert 4 Minuten. Ich lade das gleiche RTF in das RTF-Steuerelement in Wordpad von Windows XP und lädt es in 2 Sekunden.C# RichEditBox hat extrem langsame Leistung (4 Minuten Laden)

Wordpad führt 120 mal schneller als meine Anwendung.

Was ist der Grund, und wie kann ich es beheben?

Antwort

20

Ich habe den Quellcode von Wordpad (http://download.microsoft.com/download/4/0/9/40946FEC-EE5C-48C2-8750-B0F8DA1C99A8/MFC/ole/wordpad.zip.exe) heruntergeladen und es hat die gleiche schlechteste Leistung (4 Minuten). Aber dieses Beispiel ist eine alte Version von Wordpad.

So hat Microsoft in den letzten Jahren alles in Wordpad verbessert, das im .NET Framework fehlt.

Schließlich fand ich die Lösung:

Der .NET-Framework als auch die alte Wordpad funktioniert die RichEdit20W Klasse für die Richedit Steuerung verwendet. Aber das Wordpad von Windows XP verwendet das neue RichEdit50W, das von Microsoft stark verbessert wurde.

Also wie sage ich dem .NET Framework, RichEdit50W anstelle von RichEdit20W zu verwenden?

Dies ist sehr einfach: Ableiten einer Klasse von RichTextBox und Schreiben eines verwalteten Wrappers für LoadLibary.

Die Klasse RichEdit50W wird von MsftEdit.dll erstellt, die seit Windows XP SP1 verfügbar ist. Ich habe einen Fallback auf RichEdit20W für den sehr seltenen Fall implementiert, dass jemand XP noch ohne Service Pack verwenden sollte.

Und es funktioniert!

/// <summary> 
/// The framework uses by default "Richedit20W" in RICHED20.DLL. 
/// This needs 4 minutes to load a 2,5MB RTF file with 45000 lines. 
/// Richedit50W needs only 2 seconds for the same RTF document !!! 
/// </summary> 
protected override CreateParams CreateParams 
{ 
    get 
    { 
     CreateParams i_Params = base.CreateParams; 
     try 
     { 
      // Available since XP SP1 
      Win32.LoadLibrary("MsftEdit.dll"); // throws 

      // Replace "RichEdit20W" with "RichEdit50W" 
      i_Params.ClassName = "RichEdit50W"; 
     } 
     catch 
     { 
      // Windows XP without any Service Pack. 
     } 
     return i_Params; 
    } 
} 

HINWEIS: Siehe http://msdn.microsoft.com/en-us/library/windows/desktop/bb787873%28v=vs.85%29.aspx

public class Win32 
{ 
    [DllImport("kernel32.dll", EntryPoint="LoadLibraryW", CharSet=CharSet.Unicode, SetLastError=true)] 
    private static extern IntPtr LoadLibraryW(string s_File); 

    public static IntPtr LoadLibrary(string s_File) 
    { 
     IntPtr h_Module = LoadLibraryW(s_File); 
     if (h_Module != IntPtr.Zero) 
      return h_Module; 

     int s32_Error = Marshal.GetLastWin32Error(); 
     throw new Win32Exception(s32_Error); 
    } 
} 
+0

Sie wissen auch, was sonst noch mit RichEdit50W über 20W verbessert wird? Ich habe versucht, den Code für mein eigenes Programm zu verwenden, und ich kann keinen Unterschied feststellen. –

+0

Haben Sie einen großen RTF-Text mit Tausenden von Zeilen geladen, um das zu testen? Haben Sie mit SysInternals ProcessExplorer gesehen, welche DLL mit und ohne Codeänderung in Ihren Prozess geladen wird? Ich nehme an, es lädt immer die gleiche DLL. Es sollte einen großen Unterschied geben. Haben Sie einen Haltepunkt gesetzt, um zu sehen, ob der Code jemals ausgeführt wird? – Elmue

+0

Ja, eine 4MB Datei mit über 4000 Zeilen. Beide sind in weniger als 0,3 Sekunden sowohl bei der 20W- als auch bei der 50W-Version geladen. Der allgemeine Bildlauf und die Bearbeitung erscheinen so schnell. Ich habe MessageBox.Show() verwendet, um die Version von "i_Params.ClassName" anzuzeigen, bevor es "RichEdit50W" wurde, und wie erwartet war es "RichEdit20W". –

Verwandte Themen