diff --git a/src/LogExpert.UI/Controls/LogWindow/LogWindow.cs b/src/LogExpert.UI/Controls/LogWindow/LogWindow.cs index 98f99082..4ba8dd4a 100644 --- a/src/LogExpert.UI/Controls/LogWindow/LogWindow.cs +++ b/src/LogExpert.UI/Controls/LogWindow/LogWindow.cs @@ -33,7 +33,8 @@ using Vanara.Extensions; using WeifenLuo.WinFormsUI.Docking; -//using static LogExpert.PluginRegistry.PluginRegistry; //TODO: Adjust the instance name so using static can be used. +//using static LogExpert.PluginRegistry.PluginRegistry; +//TODO: Adjust the instance name so using static can be used. namespace LogExpert.UI.Controls.LogWindow; @@ -49,6 +50,7 @@ internal partial class LogWindow : DockContent, ILogPaintContextUI, ILogView, IL private const int FILTER_PANEL2_CONTROL_GAP = 6; private const int WAIT_TIME = 500; private const int OVERSCAN = 20; + private const int WORKER_SHUTDOWN_TIMEOUT = 2000; // ms to wait for a worker task to drain during teardown before giving up private const string FONT_COURIER_NEW = "Courier New"; private const string FONT_VERDANA = "Verdana"; private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); @@ -152,6 +154,7 @@ internal partial class LogWindow : DockContent, ILogPaintContextUI, ILogView, IL private int _selectedCol; // set by context menu event for column headers only private bool _shouldCallTimeSync; private bool _shouldCancel; + private bool _isClosing; // set once CloseLogWindow starts tearing down; suppresses grid CellValueNeeded callbacks private bool _shouldTimestampDisplaySyncingCancel; private bool _showAdvanced; private List _tempHighlightEntryList = []; @@ -243,7 +246,6 @@ public LogWindow (ILogWindowCoordinator logWindowCoordinator, string fileName, b advancedFilterSplitContainer.SplitterDistance = FILTER_ADVANCED_SPLITTER_DISTANCE; _timeShiftSyncTask = Task.Factory.StartNew(SyncTimestampDisplayWorker, _cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); - _logEventHandlerTask = Task.Factory.StartNew(LogEventWorker, _cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); //this.filterUpdateThread = new Thread(new ThreadStart(this.FilterUpdateWorker)); @@ -955,6 +957,12 @@ private void OnFileSizeChanged (object sender, LogEventArgs e) [SupportedOSPlatform("windows")] private void OnDataGridViewCellValueNeeded (object sender, DataGridViewCellValueEventArgs e) { + if (_isClosing) + { + e.Value = Column.EmptyColumn; + return; + } + PrefetchVisibleLines(); var startCount = CurrentColumnizer?.GetColumnCount() ?? 0; @@ -1152,7 +1160,7 @@ private void OnFilterGridViewCellPainting (object sender, DataGridViewCellPainti [SupportedOSPlatform("windows")] private void OnFilterGridViewCellValueNeeded (object sender, DataGridViewCellValueEventArgs e) { - if (e.RowIndex < 0 || e.ColumnIndex < 0 || _filterResultList.Count <= e.RowIndex) + if (_isClosing || e.RowIndex < 0 || e.ColumnIndex < 0 || _filterResultList.Count <= e.RowIndex) { e.Value = string.Empty; return; @@ -3027,10 +3035,26 @@ ExternalException or private void StopLogEventWorkerThread () { - _ = _logEventArgsEvent.Set(); + _ = _logEventArgsEvent.Set(); // wake the worker if it is parked on the event so it observes the cancel and exits _cts.Cancel(); - //_logEventHandlerThread.Abort(); - //_logEventHandlerThread.Join(); + JoinWorker(_logEventHandlerTask); + } + + /// + /// Waits (briefly) for a long-running worker task to drain during teardown. Workers observe cancellation via + /// plus their wake-up events; the bounded timeout guards against a worker blocked in I/O so + /// closing the window can never hang. Faults are swallowed because this only runs while tearing down. + /// + private static void JoinWorker (Task worker) + { + try + { + _ = worker.Wait(WORKER_SHUTDOWN_TIMEOUT); + } + catch (AggregateException) + { + // A worker threw on its way out; nothing actionable during teardown. + } } private void OnFileSizeChanged (LogEventArgs logEventArgs) @@ -3972,10 +3996,9 @@ private void StopTimespreadThread () private void StopTimestampSyncThread () { _shouldTimestampDisplaySyncingCancel = true; - //_timeShiftSyncWakeupEvent.Set(); - //_timeShiftSyncThread.Abort(); - //_timeShiftSyncThread.Join(); + _ = _timeShiftSyncWakeupEvent.Set(); // wake the worker if it is parked so it observes the cancel flag and exits _cts.Cancel(); + JoinWorker(_timeShiftSyncTask); } [SupportedOSPlatform("windows")] @@ -6632,6 +6655,8 @@ public void Close (bool dontAsk) public void CloseLogWindow () { + _isClosing = true; + CancelHighlightBookmarkScan(); StopTimespreadThread(); StopTimestampSyncThread(); diff --git a/src/PluginRegistry/PluginHashGenerator.Generated.cs b/src/PluginRegistry/PluginHashGenerator.Generated.cs index 4e1a6d65..633650c5 100644 --- a/src/PluginRegistry/PluginHashGenerator.Generated.cs +++ b/src/PluginRegistry/PluginHashGenerator.Generated.cs @@ -10,7 +10,7 @@ public static partial class PluginValidator { /// /// Gets pre-calculated SHA256 hashes for built-in plugins. - /// Generated: 2026-06-23 12:42:21 UTC + /// Generated: 2026-06-24 08:06:11 UTC /// Configuration: Release /// Plugin count: 21 /// @@ -18,27 +18,27 @@ public static Dictionary GetBuiltInPluginHashes() { return new Dictionary(StringComparer.OrdinalIgnoreCase) { - ["AutoColumnizer.dll"] = "4AE116E2581EA07B383F89E32CEB72F3A03827B330CF08C66230D649F1C58315", + ["AutoColumnizer.dll"] = "36D3E82056BBE33D1F6A32ED28107475A6E466DA11366D92BF2FC75468659BAB", ["BouncyCastle.Cryptography.dll"] = "E5EEAF6D263C493619982FD3638E6135077311D08C961E1FE128F9107D29EBC6", ["BouncyCastle.Cryptography.dll (x86)"] = "E5EEAF6D263C493619982FD3638E6135077311D08C961E1FE128F9107D29EBC6", - ["CsvColumnizer.dll"] = "32B244C68BD97A6B9321D1FC6419FFC727CB675533EF08DBB5BE74F6CAE07CE3", - ["CsvColumnizer.dll (x86)"] = "32B244C68BD97A6B9321D1FC6419FFC727CB675533EF08DBB5BE74F6CAE07CE3", - ["DefaultPlugins.dll"] = "6844A0DC8DD97FDC44434D3DD07EE84447A39249A86180FD4458021519CE478E", - ["FlashIconHighlighter.dll"] = "A2C32F6C3BDCBBBEB62F45150BB79DCE6FB3CCF4F376750B7AD1BE1012CE4923", - ["GlassfishColumnizer.dll"] = "D1945C2908C88709440232E2872F72436275F59E9E92B009B45CD2290D2B2938", - ["JsonColumnizer.dll"] = "A645233A1051878B21B2DBE14F3AF772CFBD238685E21EFA58934928BF005EBB", - ["JsonCompactColumnizer.dll"] = "2E3D7D042153D91E7D46A1EFAA58669F631E8CAA3EF5B04BBABAF33E8A6FEA5A", - ["Log4jXmlColumnizer.dll"] = "796D336CF9B6F1E3A380BC75365AB56A9A0DA53EA8FF46C72BB37EDCD0980EAF", - ["LogExpert.Resources.dll"] = "9B41E8CE1EBCD68856B36132072198D04C36F2EA000D261E0D111116E347605B", + ["CsvColumnizer.dll"] = "6AB202B1E664F587A0655C2426831FB3E5640AECC6205C4C6C147A8DC9DBEFC9", + ["CsvColumnizer.dll (x86)"] = "6AB202B1E664F587A0655C2426831FB3E5640AECC6205C4C6C147A8DC9DBEFC9", + ["DefaultPlugins.dll"] = "05783A26E389565F7D262C005F7D5CD7938738CD28A6BB5C7E7E275291616E73", + ["FlashIconHighlighter.dll"] = "C68A44AC9542B23F852B681909C1D6810246474081092432FBC507CF1E9D4038", + ["GlassfishColumnizer.dll"] = "A30C04E7C61309977731327B26AB88B01386EC96CF8D84266ACF8434E4257575", + ["JsonColumnizer.dll"] = "8600F78EF0930211D8986737D7AAC968F4EB7213CE691AFF0691A8682DF82D52", + ["JsonCompactColumnizer.dll"] = "0F77645DA79291D3CC20FD254798C0D6AB3E27DB9BA96BB04F73D566F49FDCDD", + ["Log4jXmlColumnizer.dll"] = "B502ED950944FC439634AC3F3FB45E7B2308E945CBFBEA5A3CAF1257ACF49457", + ["LogExpert.Resources.dll"] = "D44708FD8FC9F9485D8D36068A131903954E385786F0FAE78AC6EF9BDC0ED576", ["Microsoft.Extensions.DependencyInjection.Abstractions.dll"] = "67FA4325000DB017DC0C35829B416F024F042D24EFB868BCF17A895EE6500A93", ["Microsoft.Extensions.DependencyInjection.Abstractions.dll (x86)"] = "67FA4325000DB017DC0C35829B416F024F042D24EFB868BCF17A895EE6500A93", ["Microsoft.Extensions.Logging.Abstractions.dll"] = "BB853130F5AFAF335BE7858D661F8212EC653835100F5A4E3AA2C66A4D4F685D", ["Microsoft.Extensions.Logging.Abstractions.dll (x86)"] = "BB853130F5AFAF335BE7858D661F8212EC653835100F5A4E3AA2C66A4D4F685D", - ["RegexColumnizer.dll"] = "D75BB9C8347459F6D5AB1C643A04C77FBFCC688F56E3B484B8096B4BEFB4338D", - ["SftpFileSystem.dll"] = "3828CCB6B44B23804CEFF59E260E5342395BC7AF13DC7877A4FFEFF815BAB440", - ["SftpFileSystem.dll (x86)"] = "7C8B760FF3ACAF22406F04AC305872716476743542F4AB644CBEEEBF71DF03A5", - ["SftpFileSystem.Resources.dll"] = "AAAF7CF74F0F2670E7994BA10E11F1A6F55074ABE634AAF72B0058119ECC18B3", - ["SftpFileSystem.Resources.dll (x86)"] = "AAAF7CF74F0F2670E7994BA10E11F1A6F55074ABE634AAF72B0058119ECC18B3", + ["RegexColumnizer.dll"] = "9F18D9269DF2B8C482F1C82A1FDA93D1D445F0C2CEEEFA72124A9B6C4B5C1E9C", + ["SftpFileSystem.dll"] = "301D74FC8683B8D8B71A286711152ACA5581CF78D32CF9DCF218802F81D7D02B", + ["SftpFileSystem.dll (x86)"] = "2FE8EE1C55CC85AA82F4CE3B19B5E2734BC00E928D65C94E8B88695D9434AEF9", + ["SftpFileSystem.Resources.dll"] = "C39F867FFA577867BE6A7101F66D0EBA3207E2060FDE03646AC1F8D8ECCC140E", + ["SftpFileSystem.Resources.dll (x86)"] = "C39F867FFA577867BE6A7101F66D0EBA3207E2060FDE03646AC1F8D8ECCC140E", }; }