-
Notifications
You must be signed in to change notification settings - Fork 80
Open
Labels
bug 🐛Something isn't workingSomething isn't working
Description
Describe the bug
A memory leak occurs in MarkdownTextBlock when the Text property is bound to a live stream.
The same update logic works correctly with TextBox and does not exhibit any memory issues.
- Using MarkdownTextBlock causes a memory leak.
The private bytes start at around 100 MB and grow to over 3 GB after loading the entire text. - Using a TextBox instead of MarkdownTextBlock does not cause a memory leak.
The private bytes start at around 100 MB and only increase to about 150 MB after loading the entire text.
xaml code:
<Page
x:Class="Views.ChatPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:Models"
xmlns:templates="using:Templates"
xmlns:vm="using:ViewModels"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate x:Key="ModelMessageTemplate" x:DataType="models:ModelMessage">
<Grid>
<!-- Using MarkdownTextBlock causes a memory leak.
The private bytes start at around 100 MB and grow to over 3 GB after loading the entire text. -->
<controls:MarkdownTextBlock Text="{x:Bind MessageText, Mode=TwoWay}" />
<!-- Using a TextBox instead of MarkdownTextBlock does not cause a memory leak.
The private bytes start at around 100 MB and only increase to about 150 MB after loading the entire text. -->
<!-- <TextBox TextWrapping="Wrap" Text="{x:Bind MessageText, Mode=TwoWay}" /> -->
</Grid>
</DataTemplate>
<DataTemplate x:Key="PromptMessageTemplate" x:DataType="models:PromptMessage">
<Grid>
<TextBox IsReadOnly="True" Text="{x:Bind MessageText}" />
</Grid>
</DataTemplate>
<templates:MessageTemplateSelector
x:Key="MessageTemplateSelector"
ModelMessageTemplate="{StaticResource ModelMessageTemplate}"
PromptMessageTemplate="{StaticResource PromptMessageTemplate}" />
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="200" />
</Grid.RowDefinitions>
<ScrollViewer>
<ItemsControl ItemTemplateSelector="{StaticResource MessageTemplateSelector}" ItemsSource="{Binding Messages}">
</ItemsControl>
</ScrollViewer>
</Grid>
</Page>csharp code:
public partial class BaseMessage : ReactiveObject
{
[Reactive]
private string _messageText = string.Empty;
}
public partial class ModelMessage : BaseMessage
{
public Task SubscribeAsync(IAsyncEnumerable<string> strings, CancellationToken cancellationToken)
{
var observable = strings
.ToObservable()
.Buffer(TimeSpan.FromMilliseconds(100))
.Where(buffer => buffer.Count > 0)
.ObserveOn(RxApp.MainThreadScheduler);
observable.Subscribe(buffer =>
{
MessageText += string.Concat(buffer);
});
return Task.CompletedTask;
}
}public partial class ChatViewModel:ReactiveObject
{
private const string _markdown = "**"
public ObservableCollection<BaseMessage> Messages { get; } = [];
[ReactiveCommand]
public async Task SendMessage(string message)
{
var modelMessage = new ModelMessage();
Messages.Add(modelMessage);
var textStream = GetTextStream(_markdown, delayMs: 5);
_= modelMessage.SubscribeAsync(textStream,cancellationToken:System.Threading.CancellationToken.None);
}
public static async IAsyncEnumerable<string> GetTextStream(
string text,
int delayMs = 10,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
foreach (var ch in text)
{
cancellationToken.ThrowIfCancellationRequested();
yield return ch.ToString();
await Task.Delay(delayMs, cancellationToken);
}
}
** _markdown is a sample markdown code :
Labs-Windows/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs
Line 25 in 18946f6
| private const string _markdown = @" |
Steps to reproduce
- Create a new winui3 project
- Paste the code
- Run/Debug
- Start a memory profile tool:process informer
Expected behavior
Although the memory may temporarily spike to a higher value, it eventually returns to a normal level.
Screenshots
No response
Code Platform
- UWP
- WinAppSDK / WinUI 3
- Web Assembly (WASM)
- Android
- iOS
- MacOS
- Linux / GTK
Windows Build Number
- Windows 10 1809 (Build 17763)
- Windows 10 1903 (Build 18362)
- Windows 10 1909 (Build 18363)
- Windows 10 2004 (Build 19041)
- Windows 10 20H2 (Build 19042)
- Windows 10 21H1 (Build 19043)
- Windows 11 21H2 (Build 22000)
- Other (specify)
Other Windows Build number
No response
App minimum and target SDK version
- Windows 10, version 1809 (Build 17763)
- Windows 10, version 1903 (Build 18362)
- Windows 10, version 1909 (Build 18363)
- Windows 10, version 2004 (Build 19041)
- Other (specify)
Other SDK version
No response
Visual Studio Version
2022
Visual Studio Build Number
17.14.18
Device form factor
Desktop
Additional context
No response
Help us help you
Yes, I'd like to be assigned to work on this item.
Metadata
Metadata
Assignees
Labels
bug 🐛Something isn't workingSomething isn't working