【问题标题】:RichEditBox performance slow when dealing with larger text files (loading + scrolling)处理较大的文本文件(加载+滚动)时,RichEditBox 性能变慢
【发布时间】:2017-08-04 16:56:53
【问题描述】:

我正在开发一个 C#/Xaml UWP 文本编辑应用程序,它使用 RichEditBox 控件来编辑文本文件。但是,我注意到当我加载较大的文件(约 1mb 及以上,甚至可能更少)时,控制在几个关键领域会遇到困难:1)加载文件内容需要一段时间,2)一旦加载终于有了,滚动非常生涩,输入文件既不流畅也不响应。

我遇到的最接近的答案是this(它所描述的正是我遇到的问题),但它似乎不适用于 UWP 应用。

编辑:

当我打开一个文件时,要分享的值得注意的代码是:

_currentFile.Content = await readFile(file);
_currentFile._richeditbox.Document.SetText(TextSetOptions.None, _currentFile.Content);

这是 readFile() 函数,通过 https://social.msdn.microsoft.com/Forums/sqlserver/en-US/0f3cd056-a2e3-411b-8e8a-d2109255359a/uwpc-reading-ansi-text-file?forum=wpdevelop 得到帮助:

private async Task<string> readFile(StorageFile file)
{
    string charSet = null;

    try
    {
        await Task.Run(() =>
         {
             try
             {
                 using (FileStream fs = System.IO.File.OpenRead(file.Path))
                 {
                     Ude.CharsetDetector cdet = new Ude.CharsetDetector();
                     cdet.Feed(fs);
                     cdet.DataEnd();
                     charSet = cdet.Charset;
                 }
             }
             catch (Exception ex)
             {

             }
         });
    }
    catch (Exception e)
    {

    }

    Classes.File._lastEncoding = charSet;

    IBuffer buffer = await FileIO.ReadBufferAsync(file);
    DataReader reader = DataReader.FromBuffer(buffer);
    byte[] fileContent = new byte[reader.UnconsumedBufferLength];
    reader.ReadBytes(fileContent);
    string content = "";
    if (charSet == "windows-1252")
    {
        content = Encoding.GetEncoding("iso-8859-1").GetString(fileContent, 0, fileContent.Length);
    }
    else if (charSet == "UTF-16LE")
    {
        content = Encoding.Unicode.GetString(fileContent, 0, fileContent.Length);
    }
    else if (charSet == "UTF-16BE")
    {
        content = Encoding.BigEndianUnicode.GetString(fileContent, 0, fileContent.Length);
    }
    else
    {
        content = Encoding.UTF8.GetString(fileContent, 0, fileContent.Length);
    }

    return content;
} 

调试时,调用readFile()函数绝对没有延迟;它执行得非常快。

我尝试加载一个 1.14mb 的文本文件。加载需要一些时间,当它加载时,虽然滚动条高度表明它已全部加载,但实际上从第 2098 行开始并没有显示任何文本(总共有 3,771 行);即使在后续重新加载时,它也会始终停在这一行。

看图:

您还可以看到,可见的最后一行与上面的行混在一起。

作为参考,我遇到问题的文件可以从这里下载(但要明确的是,所有类似大小的文本文件都有问题,甚至可能更小):http://mtrostyle.net/appytext/testfile.txt

【问题讨论】:

  • 我尝试加载一个 138M 大小的 rtf 文件。但是,我无法重现您的问题。你能分享更多关于如何加载文件的代码吗?
  • 我已经更新了值得注意的代码和其他信息。感谢您查看此 Nico,非常感谢。

标签: c# performance xaml uwp richeditbox


【解决方案1】:

是的,当我加载您提供的 txt 文件时,我得到了相同的结果。我一直在向相关团队报告这个问题。目前,显示文件的一种解决方法是在WebView 控件中呈现文本。并为WebView 设置导入导出。更多内容可以参考WebView

<body>
    <textarea id="input" style="width:100%; height:400px;"></textarea>
    <script type="text/javascript">
        function SetText(text) {
            document.getElementById('input').textContent = text;
        }
        function SaveText() {
            var note = document.getElementById('input').textContent;
            window.external.notify(note);
        }
    </script>
</body>

MainPage.xaml

  <WebView x:Name="MyWebView" Source="ms-appx-web:///HomePage.html" Height="400" />

MainPage.xaml.cs

public MainPage()
{
    this.InitializeComponent();
    MyWebView.ScriptNotify += MyWebView_ScriptNotify;
}

private void MyWebView_ScriptNotify(object sender, NotifyEventArgs e)
{
    var saveText = e.Value.ToString();
}

private async void Button_Click(object sender, RoutedEventArgs e)
{
    Windows.Storage.Pickers.FileOpenPicker open =
            new Windows.Storage.Pickers.FileOpenPicker();
    open.SuggestedStartLocation =
        Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
    open.FileTypeFilter.Add(".rtf");
    open.FileTypeFilter.Add(".txt");

    Windows.Storage.StorageFile file = await open.PickSingleFileAsync();

  if (file != null)
   {
     var Content = await readFile(file);
     string[] args = { Content };
     await MyWebView.InvokeScriptAsync("SetText", args);
   } 

}

private async Task<string> readFile(StorageFile file)
{
    string charSet = null;

    try
    {
        await Task.Run(async () =>
        {
            try
            {
                using (var fs = await file.OpenAsync(FileAccessMode.Read))
                {
                    var tem = fs.AsStream();
                    Ude.CharsetDetector cdet = new Ude.CharsetDetector();
                    cdet.Feed(tem);
                    cdet.DataEnd();
                    charSet = cdet.Charset;
                }
            }
            catch (Exception ex)
            {
            }
        });
    }
    catch (Exception e)
    {
    }

    IBuffer buffer = await FileIO.ReadBufferAsync(file);
    DataReader reader = DataReader.FromBuffer(buffer);
    byte[] fileContent = new byte[reader.UnconsumedBufferLength];
    reader.ReadBytes(fileContent);
    string content = "";
    if (charSet == "windows-1252")
    {
        content = Encoding.GetEncoding("iso-8859-1").GetString(fileContent, 0, fileContent.Length);
    }
    else if (charSet == "UTF-16LE")
    {
        content = Encoding.Unicode.GetString(fileContent, 0, fileContent.Length);
    }
    else if (charSet == "UTF-16BE")
    {
        content = Encoding.BigEndianUnicode.GetString(fileContent, 0, fileContent.Length);
    }
    else
    {
        content = Encoding.UTF8.GetString(fileContent, 0, fileContent.Length);
    }

    return content;
}

private async void Button_Click_1(object sender, RoutedEventArgs e)
{
    await MyWebView.InvokeScriptAsync("SaveText", null);
}

【讨论】:

  • 嗯,好吧,至少这很好,因为问题是可重现的。也感谢您与相关团队分享它,希望这可以得到解决,因为我认为这是商店中所有文本编辑应用程序(即许多应用程序)的基本要求。不过,根据您的建议,首先我使用的是 Xaml,而不是 JS。 JS 代码是否要插入到 Webview 要呈现的 HTML 文件中?为了使文本可编辑,我该怎么做?我是否将 Webview 的内容复制到 RichEditBox?显然这并不理想,如果它确实有效,我将仅限于大文件。
  • 可能还值得指出的是,我确实遇到了另一个与我的非常相似的 Stack Overflow 问题:stackoverflow.com/questions/18668920/…。有趣的是,这个问题似乎已经有一段时间了。它实际上有一个解决方案,但不幸的是不适用于 UWP(我不认为)。但也许它可以成为您/其他人调查此事的线索。
  • 是的。我很想听听你的建议。上面的答案是完整的,它通过 ScriptNotify 方法提供了完整的输入和输出功能。不过,确实是治标不治本!我期待您的更多反馈,以便我们提高质量。最好的问候。
  • 大家好。到目前为止,我参与的一个项目正遭受紧张滚动的困扰,因为我们正在使用大量的 Richeditbox 作为具有大量项目的 GRIDVIEW 的数据模板。即使我们每个项目的数据非常少,我们在滚动期间的性能也很差,richeditbox 中的内容加载时间太长。如果在提高 Richeditbox 数据加载性能方面有任何新进展,请提供帮助并分享
猜你喜欢
  • 2023-03-25
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
  • 2016-04-28
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多