Skip to content

Commit a53310c

Browse files
committed
fix: Use EnableCollectionSynchronization on GUI log
We update the log GUI from multiple threads, so just use EnableCollectionSynchronization to make sure all functions of that collection that need to be sync'd are. Fixes #274
1 parent 033512a commit a53310c

1 file changed

Lines changed: 15 additions & 40 deletions

File tree

Buttplug.Components.Controls/ButtplugLogControl.xaml.cs

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
using System;
1+
using Buttplug.Core;
2+
using Microsoft.Win32;
3+
using NLog;
4+
using NLog.Config;
5+
using NLog.Targets;
6+
using System;
27
using System.Collections.ObjectModel;
38
using System.Linq;
49
using System.Text;
5-
using System.Threading;
6-
using System.Threading.Tasks;
710
using System.Windows;
811
using System.Windows.Controls;
12+
using System.Windows.Data;
913
using System.Windows.Input;
10-
using System.Windows.Threading;
11-
using Buttplug.Core;
12-
using Microsoft.Win32;
13-
using NLog;
14-
using NLog.Config;
15-
using NLog.Targets;
16-
using System.Collections.Specialized;
1714

1815
namespace Buttplug.Components.Controls
1916
{
@@ -25,44 +22,22 @@ public class LogList : ObservableCollection<string>
2522
public sealed class ButtplugGUIMessageNLogTarget : TargetWithLayoutHeaderAndFooter
2623
{
2724
private readonly LogList _logs;
28-
private readonly Thread _winThread;
25+
private readonly object _logLock = new object();
2926
public long MaxLogs;
3027

31-
public ButtplugGUIMessageNLogTarget(LogList aList, Thread aWinThread, long aMaxLogs = 1000)
28+
public ButtplugGUIMessageNLogTarget(LogList aList, long aMaxLogs = 1000)
3229
{
33-
// TODO This totally needs a mutex or something
3430
_logs = aList;
35-
_winThread = aWinThread;
3631
MaxLogs = aMaxLogs;
32+
BindingOperations.EnableCollectionSynchronization(_logs, _logLock);
3733
}
3834

3935
protected override void Write(LogEventInfo aLogEvent)
4036
{
41-
try
42-
{
43-
if (_winThread != Dispatcher.CurrentDispatcher.Thread)
44-
{
45-
Dispatcher.FromThread(_winThread).Invoke(() =>
46-
{
47-
_logs.Add(Layout.Render(aLogEvent));
48-
while (_logs.Count > MaxLogs)
49-
{
50-
_logs.RemoveAt(0);
51-
}
52-
});
53-
}
54-
else
55-
{
56-
_logs.Add(Layout.Render(aLogEvent));
57-
while (_logs.Count > MaxLogs)
58-
{
59-
_logs.RemoveAt(0);
60-
}
61-
}
62-
}
63-
catch (TaskCanceledException)
37+
_logs.Add(Layout.Render(aLogEvent));
38+
while (_logs.Count > MaxLogs)
6439
{
65-
// noop
40+
_logs.RemoveAt(0);
6641
}
6742
}
6843
}
@@ -97,7 +72,7 @@ public ButtplugLogControl()
9772
// Null check Dispatcher, otherwise test bringup for GUI tests will fail.
9873
if (Dispatcher != null)
9974
{
100-
_logTarget = new ButtplugGUIMessageNLogTarget(_logs, Dispatcher.Thread);
75+
_logTarget = new ButtplugGUIMessageNLogTarget(_logs);
10176
c.AddTarget("ButtplugGuiLogger", _logTarget);
10277
_outgoingLoggingRule = new LoggingRule("*", LogLevel.Debug, _logTarget);
10378
c.LoggingRules.Add(_outgoingLoggingRule);
@@ -209,4 +184,4 @@ private void LogListBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e
209184
}
210185
}
211186
}
212-
}
187+
}

0 commit comments

Comments
 (0)