Подтвердить что ты не робот

С# RichEditBox имеет чрезвычайно низкую производительность (4 минуты загрузки)

Элемент управления RichEditBox в С# (я использую VS 2005) имеет плохую производительность. Я загружаю файл RTF размером 2,5 МБ с 45 000 цветных строк текста в элемент управления и занимает 4 минуты. Я загружаю тот же RTF в элемент управления RTF в Wordpad Windows XP, и он загружается через 2 секунды.

Wordpad выполняет в 120 раз быстрее, чем мое приложение.

В чем причина и как его исправить?

4b9b3361

Ответ 1

Я загрузил исходный код Wordpad (http://download.microsoft.com/download/4/0/9/40946FEC-EE5C-48C2-8750-B0F8DA1C99A8/MFC/ole/wordpad.zip.exe), и он имеет ту же самую худшую производительность (4 минуты). Но этот образец является старой версией Wordpad.

Итак, Microsoft в последние годы улучшила что-либо в Wordpad, что отсутствует в платформе .NET.

Наконец, я нашел решение:

В .NET Framework используется класс RichEdit20W для элемента Richedit, также как и старый Wordpad. Но Wordpad Windows XP использует новый RichEdit50W, который Microsoft значительно улучшил.

Итак, как я могу сказать платформе .NET использовать RichEdit50W вместо RichEdit20W?

Это очень просто: выведите класс из RichTextBox и напишите управляемую оболочку для LoadLibary.

Класс RichEdit50W создается MsftEdit.dll, который доступен с Windows XP SP1. Я реализовал резервную копию RichEdit20W для очень редкого случая, когда кто-то должен использовать XP без пакета обновления.

И он работает!

/// <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;
    }
}

ПРИМЕЧАНИЕ. См. также 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);
    }
}

Ответ 2

Спасибо Elmue, это улучшило мою производительность RTF с 38 секунд до <1,5 секунд