-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WPF TextBox stutters on update #5887
Comments
You can get slightly better results by using background/server GC.
Otherwise if being interrupted by GC is not acceptable than perhaps managed runtime is not the best tool for the task. |
Well, I lost my time machine to be able to unselect the choice of a Managed language often times used to code games without stutter. It is true that you practically can't edit while values are changing but the components are not always changing rapidly and the end user needs to be able to change them manually from time to time and I guess that is why a textbox was choosen. However, The ability to track a click to Edit should not mean bad performance. My scenario is not a performance intensive one considering all games etc being written in c#. I do NOT even have a lot components in the example . Obviously something should be considered wrong and it would benefit a lot of People to fix them! |
We are also now running into this issue (we've migrated some MFC code over to WPF) and is causing our 3D view to stutter when a user pans/rotates/etc since the camera locations that are being tracked in a few text boxes (which they can edit manually at any time). The whole application can lock up for upwards of 2-4 seconds every so often which is not a very good user experience. In doing a little debugging I found it was due to an apparent deadlock that occurs every so often with the how WPF interacts with the thread input manager. I did find that the following registry setting can avoid the issue (which seems better than a GC hack, that actually causes worse performance in our case):
With this setting there is no stutter at all, perhaps @JensNordenbro you can verify this on your end too. What I'd like to know is, if our software sets the above registry value when installed what are the consequences? What feature(s) would be lost? Is there any progress on this issue, any hints at what we can do to try to fix it ourselves, or any way to bump its priority? Here's what it looks like: Screen.Recording.2023-06-23.at.10.19.47.AM.mp4Thanks! |
Just posting an update here, I've been poking away at this for a while and found that using TextBoxPerformance-TrySetNoGCRegion.mp4Here's the test code: public partial class MainWindow : Window
{
List<TextBox> textBoxes = new List<TextBox>();
public MainWindow()
{
InitializeComponent();
for (int y = 0; y < 10; y++)
{
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
for (int x = 0; x < 10; x++)
{
if (y == 0)
{
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star)});
}
var tb = new TextBox();
Grid.SetColumn(tb, x);
Grid.SetRow(tb, y);
textBoxes.Add(tb);
grid.Children.Add(tb);
}
}
var timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(0.01);
timer.Tick += Timer_Tick;
timer.Start();
}
private void Timer_Tick(object? sender, EventArgs e)
{
var rnd = new Random();
foreach (var tb in textBoxes)
{
var ret = noGCRegion.IsChecked == true && GC.TryStartNoGCRegion(10000000);
tb.Text = rnd.Next(int.MaxValue).ToString();
if (ret)
GC.EndNoGCRegion();
}
}
} |
The TextStore in TextBox should interop with native code, such as IME and so on. The GC need cost more to keep the memory safe. That means the @cwensley Another possible approach is to configure DispatcherPriority in DispatcherTimer, see: // DispatcherPriority.Loaded = 6
// DispatcherPriority.Render = 7
// DispatcherPriority.Loaded < DispatcherPriority.Render
var timer = new DispatcherTimer(DispatcherPriority.Loaded); |
I can confirm that the registry setting makes the stutter go away ! |
@lindexi thanks for the feedback, it is very much appreciated.
I'm not sure I follow here, temporarily disabling any GC from happening while setting the Text should still allow interop with native code, IME, etc. I'm not sure how this would also not allow the memory to be safe, from what I understand is it would simply defer the GC to sometime outside of setting that property.
I'm not sure that this is just a missed UI refresh, the whole application hangs and is unresponsive.
The sample is using a DispatchTimer to simulate many events happening in quick succession, this is not the case in our real-world example. If you look at my previous video this happens when using the mouse to manipulate a 3D view which in turn updates only 6 TextBox controls. I have tried to minimize the rate in which they are updated, but even limiting it to 5 updates per second vs 20-30 (which is actually horrible from a user perspective) still yields the same performance/hang issue. |
@cwensley Thank you for your reply. I can't answer your question until I know more. |
@JensNordenbro I do not know what happen... |
Ok. @cwensley? |
@JensNordenbro All I can say is that the |
Ok, Thanks guys. |
Problem description:
The attached example WPF application has a number of System.Windows.Controls.TextBox instances that are updated each 100ms when the "Go" button is pressed.
The Go button starts an update of the value Data bound to all TextBox:es according to:
The UI freezes quite quickly although I have ample of system resources:
Processor Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz 2.90 GHz
Installed RAM 64,0 GB (63,8 GB usable)
System type 64-bit operating system, x64-based processor
During net framework era we have employed a trick that adds memory pressure and garbage collects "all the time" so that a bug garbage collect that seems to cause the freeze does not need to happen. This however is not a good long term solution:
(The "solution" was initially described in http://connect.microsoft.com/VisualStudio/feedback/details/376495/wpf-sporadically-slow-textbox-text-anystring that is no longer available. )
This can be tested by checking the checkbox "UseUglyMitigation" in the first image.
Repro by running the attached application.
WpfTextBoxPerfIssue.zip
The text was updated successfully, but these errors were encountered: