NavigationPagePerformancePage.xaml.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System.Collections.Generic;
  2. using System.Threading.Tasks;
  3. using Avalonia.Controls;
  4. using Avalonia.Interactivity;
  5. namespace ControlCatalog.Pages
  6. {
  7. public partial class NavigationPagePerformancePage : UserControl
  8. {
  9. private readonly NavigationPerformanceMonitorHelper _perf = new();
  10. private int _pageCounter;
  11. private readonly List<(Border Container, Border Badge, TextBlock IndexText,
  12. TextBlock TitleText, TextBlock BadgeText)> _stackRowCache = new();
  13. public NavigationPagePerformancePage()
  14. {
  15. InitializeComponent();
  16. DemoNav.Pushed += OnStackChanged;
  17. DemoNav.Popped += OnStackChanged;
  18. DemoNav.PoppedToRoot += OnStackChanged;
  19. _ = InitializeAsync();
  20. }
  21. private async System.Threading.Tasks.Task InitializeAsync()
  22. {
  23. _perf.InitHeap();
  24. _perf.OpStopwatch.Restart();
  25. _pageCounter++;
  26. await DemoNav.PushAsync(_perf.BuildTrackedPage("Home", _pageCounter), null);
  27. _perf.OpStopwatch.Stop();
  28. Log("Init", "Pushed root page");
  29. }
  30. protected override void OnUnloaded(RoutedEventArgs e)
  31. {
  32. base.OnUnloaded(e);
  33. _perf.StopAutoRefresh();
  34. }
  35. private void OnStackChanged(object? sender, NavigationEventArgs e) => RefreshAll();
  36. private async void OnPush(object? sender, RoutedEventArgs e)
  37. {
  38. _pageCounter++;
  39. var page = _perf.BuildTrackedPage($"Page {_pageCounter}", _pageCounter);
  40. _perf.OpStopwatch.Restart();
  41. await DemoNav.PushAsync(page);
  42. _perf.StopMetrics(LastOpTimeText);
  43. Log("Push", $"Pushed \"{page.Header}\"");
  44. }
  45. private async void OnPush5(object? sender, RoutedEventArgs e)
  46. {
  47. int first = _pageCounter + 1;
  48. _perf.OpStopwatch.Restart();
  49. for (int i = 0; i < 5; i++)
  50. {
  51. _pageCounter++;
  52. await DemoNav.PushAsync(_perf.BuildTrackedPage($"Page {_pageCounter}", _pageCounter));
  53. }
  54. _perf.StopMetrics(LastOpTimeText);
  55. Log("Push ×5", $"Pushed pages {first}–{_pageCounter}");
  56. }
  57. private async void OnPop(object? sender, RoutedEventArgs e)
  58. {
  59. if (DemoNav.StackDepth > 1)
  60. {
  61. var header = DemoNav.CurrentPage?.Header?.ToString();
  62. _perf.OpStopwatch.Restart();
  63. await DemoNav.PopAsync();
  64. _perf.StopMetrics(LastOpTimeText);
  65. Log("Pop", $"Popped \"{header}\"");
  66. }
  67. }
  68. private async void OnPopToRoot(object? sender, RoutedEventArgs e)
  69. {
  70. if (DemoNav.StackDepth > 1)
  71. {
  72. int removed = DemoNav.StackDepth - 1;
  73. _perf.OpStopwatch.Restart();
  74. await DemoNav.PopToRootAsync();
  75. _perf.StopMetrics(LastOpTimeText);
  76. Log("PopToRoot", $"Removed {removed} page(s)");
  77. }
  78. }
  79. private void OnForceGC(object? sender, RoutedEventArgs e)
  80. {
  81. _perf.ForceGC(RefreshAll);
  82. Log("GC", "Forced full garbage collection");
  83. }
  84. private void OnClearLog(object? sender, RoutedEventArgs e) => LogPanel.Children.Clear();
  85. private void OnAutoRefreshChanged(object? sender, RoutedEventArgs e) =>
  86. _perf.OnAutoRefreshChanged(AutoRefreshCheck, RefreshAll);
  87. private void RefreshAll()
  88. {
  89. StackDepthText.Text = $"Stack Depth: {DemoNav.StackDepth}";
  90. LiveInstancesText.Text = $"Live Page Instances: {_perf.CountLiveInstances()}";
  91. TotalCreatedText.Text = $"Total Pages Created: {_perf.TotalCreated}";
  92. _perf.UpdateHeapDelta(ManagedMemoryText, MemoryDeltaText);
  93. NavigationPerformanceMonitorHelper.RefreshStackPanel(
  94. StackItemsPanel, _stackRowCache,
  95. DemoNav.NavigationStack, DemoNav.CurrentPage);
  96. }
  97. private void Log(string action, string detail) =>
  98. _perf.LogOperation(action, detail, LogPanel, LogScrollViewer,
  99. $"depth {DemoNav.StackDepth}");
  100. }
  101. }