From 793dd8289af37edfb487ce280c124bcbdfda9f07 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sun, 28 Mar 2021 21:30:42 -0700 Subject: [PATCH] Safer queue, use LogLine struct again Once ConcurrentQueue was used, there were issues with using Run objects in the queue. Even with Dispatcher, there were access issues. So back to the minimal struct. --- MPF/UserControls/LogOutput.xaml.cs | 44 ++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/MPF/UserControls/LogOutput.xaml.cs b/MPF/UserControls/LogOutput.xaml.cs index 10f398e0..4ca3d8df 100644 --- a/MPF/UserControls/LogOutput.xaml.cs +++ b/MPF/UserControls/LogOutput.xaml.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -26,7 +27,7 @@ namespace MPF.UserControls /// /// Queue of items that need to be logged /// - private readonly Queue logQueue; + private readonly ConcurrentQueue logQueue; /// /// List of Matchers for progress tracking @@ -57,7 +58,7 @@ namespace MPF.UserControls AddAaruMatchers(); AddDiscImageCreatorMatchers(); - logQueue = new Queue(); + logQueue = new ConcurrentQueue(); Task.Run(() => ProcessLogLines()); } @@ -223,6 +224,18 @@ namespace MPF.UserControls #region Logging + private struct LogLine + { + public readonly string Text; + public readonly Brush Foreground; + + public LogLine(string text, Brush foreground) + { + this.Text = text; + this.Foreground = foreground; + } + } + /// /// Enqueue text to the log /// @@ -295,10 +308,7 @@ namespace MPF.UserControls brush = Brushes.Yellow; // Enqueue the text - lock (logQueue) - { - logQueue.Enqueue(new Run { Text = text, Foreground = brush }); - } + logQueue.Enqueue(new LogLine(text, brush)); } /// @@ -313,10 +323,11 @@ namespace MPF.UserControls continue; // Get the next item from the queue - var nextLogLine = logQueue.Dequeue(); - string nextText = Dispatcher.Invoke(() => nextLogLine.Text); + if (!logQueue.TryDequeue(out LogLine nextLogLine)) + continue; // Null text gets ignored + string nextText = Dispatcher.Invoke(() => nextLogLine.Text); if (nextText == null) continue; @@ -372,7 +383,7 @@ namespace MPF.UserControls catch (Exception ex) { // In the event that something fails horribly, we want to log - AppendToTextBox(new Run { Text = ex.ToString(), Foreground = Brushes.Red }); + AppendToTextBox(new LogLine(ex.ToString(), Brushes.Red)); } } } @@ -380,11 +391,12 @@ namespace MPF.UserControls /// /// Append log line to the log text box /// - /// Run value to append - private void AppendToTextBox(Run run) + /// LogLine value to append + private void AppendToTextBox(LogLine logLine) { Dispatcher.Invoke(() => { + var run = new Run { Text = logLine.Text, Foreground = logLine.Foreground }; _paragraph.Inlines.Add(run); lastLine = run; }); @@ -416,10 +428,14 @@ namespace MPF.UserControls /// /// Replace the last line written to the log text box /// - /// Run value to append - private void ReplaceLastLine(Run run) + /// LogLine value to append + private void ReplaceLastLine(LogLine logLine) { - Dispatcher.Invoke(() => { lastLine = run; }); + Dispatcher.Invoke(() => + { + lastLine.Text = logLine.Text; + lastLine.Foreground = logLine.Foreground; + }); } #endregion