From 55b5d7eecd5bdd6947b54eadb5a2e61825242f14 Mon Sep 17 00:00:00 2001 From: Jason Elkin Date: Wed, 29 Jan 2025 12:13:50 +0000 Subject: [PATCH] Fix task return and apply correct disposal pattern for FileSystemMainDomLock (#18147) --- .../Runtime/FileSystemMainDomLock.cs | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs b/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs index 3bfa50c4b1..403bde229a 100644 --- a/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs +++ b/src/Umbraco.Infrastructure/Runtime/FileSystemMainDomLock.cs @@ -15,6 +15,7 @@ internal class FileSystemMainDomLock : IMainDomLock private readonly string _lockFilePath; private readonly ILogger _logger; private readonly string _releaseSignalFilePath; + private bool _disposed; private Task? _listenForReleaseSignalFileTask; private FileStream? _lockFileStream; @@ -89,16 +90,14 @@ internal class FileSystemMainDomLock : IMainDomLock ListeningLoop, _cancellationTokenSource.Token, TaskCreationOptions.LongRunning, - TaskScheduler.Default); + TaskScheduler.Default) + .Unwrap(); // Because ListeningLoop is an async method, we need to use Unwrap to return the inner task. return _listenForReleaseSignalFileTask; } - public void Dispose() - { - _lockFileStream?.Close(); - _lockFileStream = null; - } + /// Releases the resources used by this . + public void Dispose() => Dispose(true); public void CreateLockReleaseSignalFile() => File.Open(_releaseSignalFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, @@ -108,6 +107,26 @@ internal class FileSystemMainDomLock : IMainDomLock public void DeleteLockReleaseSignalFile() => File.Delete(_releaseSignalFilePath); + /// Releases the resources used by this . + /// true to release both managed resources. + protected virtual void Dispose(bool disposing) + { + if (disposing && !_disposed) + { + _logger.LogDebug($"{nameof(FileSystemMainDomLock)} Disposing..."); + _cancellationTokenSource.Cancel(); + _cancellationTokenSource.Dispose(); + ReleaseLock(); + _disposed = true; + } + } + + private void ReleaseLock() + { + _lockFileStream?.Close(); + _lockFileStream = null; + } + private async Task ListeningLoop() { while (true) @@ -118,6 +137,7 @@ internal class FileSystemMainDomLock : IMainDomLock { _logger.LogDebug("ListenAsync Task canceled, exiting loop"); } + return; } @@ -127,12 +147,12 @@ internal class FileSystemMainDomLock : IMainDomLock { _logger.LogDebug("Found lock release signal file, releasing lock on {lockFilePath}", _lockFilePath); } - _lockFileStream?.Close(); - _lockFileStream = null; + + ReleaseLock(); break; } - await Task.Delay(_globalSettings.CurrentValue.MainDomReleaseSignalPollingInterval); + await Task.Delay(_globalSettings.CurrentValue.MainDomReleaseSignalPollingInterval, _cancellationTokenSource.Token); } } }