处理较大的文本文件时RichEditBox性能变慢(加载+滚动)

时间:2017-08-01 22:26:51

标签: c# performance xaml uwp richeditbox

我正在开发一个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行);即使在后续重新加载时,它也会始终停在此线上。

见图:

enter image description here

您还可以看到可见的最后一行被其上面的行混淆。

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

1 个答案:

答案 0 :(得分:0)

是的,当我加载你提供的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);
}