将文本 属性 设置为大字符串时 WPF 文本框元素冻结
WPF Textbox Element freezes when setting the text property to a large string
我目前正在开发一个 UWP 应用程序,我遇到了一个问题
TextBox WPF Element,在处理较大的文本时似乎性能很差。将剪贴板中的大文本粘贴到文本框中效果非常好,但是当我尝试以编程方式设置文本时,它会冻结整个应用程序:
textbox.Text = sb.ToString(); //Freezes or takes for ever
这就是我在 MainPage.xaml 中定义文本框的方式:
<TextBox x:Name="textbox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" Margin="0,0,0,70"/>
有没有人知道这个性能问题的解决方案或者是
有我可以使用的替代文本字段元素吗?
好的......我已经能够得到添加文本所需的时间,最多需要 133 毫秒,这是我发现的最高时间。那是轻微的抖动;如果我添加 50K 个字符,大约需要 1000 毫秒,这很明显,但考虑到字符数,还算不错。
为了执行测试,我首先创建了一个视图:
ProgressBar
检测 UI 冻结/抖动。
TextBlock
以毫秒为单位显示添加文本所需的时间。
Button
开始添加文本。
TextBox
将文本添加到。
MainPage.xaml
<Page x:Class="Question_Answer_UWPApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ProgressBar Name="progressBarAddingText"
IsIndeterminate="True" />
<TextBlock Name="textBlockAddingTextTime" />
<Button Content="Add Text"
Click="ButtonClick" />
<TextBox Name="textBoxAddingText"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Auto"
TextWrapping="Wrap"
Margin="0,0,0,70" />
</StackPanel>
</Page>
MainPage.xaml.cs
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;
namespace Question_Answer_UWPApp
{
public sealed partial class MainPage : Page
{
public static Stopwatch stopwatch = new Stopwatch();
public MainPage()
{
InitializeComponent();
}
public async void AddTextAsynchronously()
{
var text = await Task.Run(() =>
{
var stringBuilder = new StringBuilder();
for (int i = 0; i < 5000; i++)
stringBuilder.Append("X");
return stringBuilder.ToString();
});
stopwatch.Start();
textBoxAddingText.Text = text;
stopwatch.Stop();
textBlockAddingTextTime.Text = $"{stopwatch.ElapsedMilliseconds.ToString()} milliseconds";
}
private void ButtonClick(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
AddTextAsynchronously();
}
}
}
在这个测试中,我得到了大约 133ms,但是当我将 StringBuilder
放在 Task
之外并使用 Task
只是为了构建 StringBuilder
(本质上允许我要说 .Text = stringBuilder.ToString()
还需要大约 10 毫秒。这意味着 StringBuilder
不是瓶颈。我不认为将文本添加到 TextBox
是你的瓶颈要么。
通过这个测试,我觉得你应该在其他地方寻找你的瓶颈。这应该可以安全地回答通过代码向 TextBox
添加文本并不耗时的问题。
我目前正在开发一个 UWP 应用程序,我遇到了一个问题 TextBox WPF Element,在处理较大的文本时似乎性能很差。将剪贴板中的大文本粘贴到文本框中效果非常好,但是当我尝试以编程方式设置文本时,它会冻结整个应用程序:
textbox.Text = sb.ToString(); //Freezes or takes for ever
这就是我在 MainPage.xaml 中定义文本框的方式:
<TextBox x:Name="textbox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" Margin="0,0,0,70"/>
有没有人知道这个性能问题的解决方案或者是 有我可以使用的替代文本字段元素吗?
好的......我已经能够得到添加文本所需的时间,最多需要 133 毫秒,这是我发现的最高时间。那是轻微的抖动;如果我添加 50K 个字符,大约需要 1000 毫秒,这很明显,但考虑到字符数,还算不错。
为了执行测试,我首先创建了一个视图:
ProgressBar
检测 UI 冻结/抖动。
TextBlock
以毫秒为单位显示添加文本所需的时间。
Button
开始添加文本。
TextBox
将文本添加到。
MainPage.xaml
<Page x:Class="Question_Answer_UWPApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ProgressBar Name="progressBarAddingText"
IsIndeterminate="True" />
<TextBlock Name="textBlockAddingTextTime" />
<Button Content="Add Text"
Click="ButtonClick" />
<TextBox Name="textBoxAddingText"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Auto"
TextWrapping="Wrap"
Margin="0,0,0,70" />
</StackPanel>
</Page>
MainPage.xaml.cs
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;
namespace Question_Answer_UWPApp
{
public sealed partial class MainPage : Page
{
public static Stopwatch stopwatch = new Stopwatch();
public MainPage()
{
InitializeComponent();
}
public async void AddTextAsynchronously()
{
var text = await Task.Run(() =>
{
var stringBuilder = new StringBuilder();
for (int i = 0; i < 5000; i++)
stringBuilder.Append("X");
return stringBuilder.ToString();
});
stopwatch.Start();
textBoxAddingText.Text = text;
stopwatch.Stop();
textBlockAddingTextTime.Text = $"{stopwatch.ElapsedMilliseconds.ToString()} milliseconds";
}
private void ButtonClick(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
AddTextAsynchronously();
}
}
}
在这个测试中,我得到了大约 133ms,但是当我将 StringBuilder
放在 Task
之外并使用 Task
只是为了构建 StringBuilder
(本质上允许我要说 .Text = stringBuilder.ToString()
还需要大约 10 毫秒。这意味着 StringBuilder
不是瓶颈。我不认为将文本添加到 TextBox
是你的瓶颈要么。
通过这个测试,我觉得你应该在其他地方寻找你的瓶颈。这应该可以安全地回答通过代码向 TextBox
添加文本并不耗时的问题。