diff --git a/.editorconfig b/.editorconfig index b58f07026d..26a9700098 100644 --- a/.editorconfig +++ b/.editorconfig @@ -225,6 +225,9 @@ dotnet_diagnostic.CA1305.severity = warning # not default, increased severity to # CA1822: Mark members as static dotnet_diagnostic.CA1822.severity = warning # not default, increased severity to ensure it is applied +# CA1816: Dispose methods should call SuppressFinalize +dotnet_diagnostic.CA1816.severity = warning # not default, increased severity to ensure it is applied + #### C# Coding Conventions #### # var preferences diff --git a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/EventLogDataCollector.cs b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/EventLogDataCollector.cs index d72079d4d7..04f3f78b25 100644 --- a/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/EventLogDataCollector.cs +++ b/src/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector/EventLogDataCollector.cs @@ -91,6 +91,8 @@ public class EventLogDataCollector : DataCollector /// private readonly IDictionary _eventLogContainerMap = new Dictionary(); + private bool _isDisposed; + /// /// Initializes a new instance of the class. /// @@ -290,25 +292,33 @@ internal string WriteEventLogs(List eventLogEntries, int maxLogEn /// Not used since this class does not have a finalizer. protected override void Dispose(bool disposing) { + if (_isDisposed) + return; + base.Dispose(disposing); - // Unregister events - if (_events != null) + if (disposing) { - _events.SessionStart -= _sessionStartEventHandler; - _events.SessionEnd -= _sessionEndEventHandler; - _events.TestCaseStart -= _testCaseStartEventHandler; - _events.TestCaseEnd -= _testCaseEndEventHandler; - } + // Unregister events + if (_events != null) + { + _events.SessionStart -= _sessionStartEventHandler; + _events.SessionEnd -= _sessionEndEventHandler; + _events.TestCaseStart -= _testCaseStartEventHandler; + _events.TestCaseEnd -= _testCaseEndEventHandler; + } - // Unregister EventLogEntry Written. - foreach (var eventLogContainer in _eventLogContainerMap.Values) - { - eventLogContainer.Dispose(); + // Unregister EventLogEntry Written. + foreach (var eventLogContainer in _eventLogContainerMap.Values) + { + eventLogContainer.Dispose(); + } + + // Delete all the temp event log directories + RemoveTempEventLogDirs(_eventLogDirectories); } - // Delete all the temp event log directories - RemoveTempEventLogDirs(_eventLogDirectories); + _isDisposed = true; } #endregion diff --git a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs index fd52dbb9f2..88227019f1 100644 --- a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs +++ b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs @@ -642,18 +642,18 @@ void OnError(TestSessionEventsHandler eventsHandler, Exception? ex) #region IDisposable Support - private bool _disposedValue; // To detect redundant calls + private bool _isDisposed; // To detect redundant calls protected virtual void Dispose(bool disposing) { - if (!_disposedValue) + if (!_isDisposed) { if (disposing) { - _communicationManager?.StopClient(); + _communicationManager.StopClient(); } - _disposedValue = true; + _isDisposed = true; } } @@ -662,6 +662,7 @@ public void Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); + GC.SuppressFinalize(this); } #endregion } diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index 03837c58fa..9a2e655868 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -68,7 +68,7 @@ public void DiscoverAsync() lock (_syncObject) { - if (_disposed) + if (_isDisposed) { throw new ObjectDisposedException(nameof(DiscoveryRequest)); } @@ -110,7 +110,7 @@ public void Abort() lock (_syncObject) { - if (_disposed) + if (_isDisposed) { throw new ObjectDisposedException(nameof(DiscoveryRequest)); } @@ -149,7 +149,7 @@ bool IRequest.WaitForCompletion(int timeout) { EqtTrace.Verbose("DiscoveryRequest.WaitForCompletion: Waiting with timeout {0}.", timeout); - if (_disposed) + if (_isDisposed) { throw new ObjectDisposedException("DiscoveryRequest"); } @@ -221,7 +221,7 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete lock (_syncObject) { - if (_disposed) + if (_isDisposed) { EqtTrace.Warning("DiscoveryRequest.HandleDiscoveryComplete: Ignoring as the object is disposed."); return; @@ -311,7 +311,7 @@ public void HandleDiscoveredTests(IEnumerable? discoveredTestCases) lock (_syncObject) { - if (_disposed) + if (_isDisposed) { EqtTrace.Warning("DiscoveryRequest.HandleDiscoveredTests: Ignoring as the object is disposed."); return; @@ -336,7 +336,7 @@ public void HandleLogMessage(TestMessageLevel level, string? message) lock (_syncObject) { - if (_disposed) + if (_isDisposed) { EqtTrace.Warning("DiscoveryRequest.HandleLogMessage: Ignoring as the object is disposed."); return; @@ -476,31 +476,21 @@ private void HandleLoggerManagerDiscoveryComplete(DiscoveryCompletePayload? disc /// resetting unmanaged resources. /// public void Dispose() - { - Dispose(true); - - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) { EqtTrace.Verbose("DiscoveryRequest.Dispose: Starting."); lock (_syncObject) { - if (!_disposed) + if (!_isDisposed) { - if (disposing) + if (_discoveryCompleted != null) { - if (_discoveryCompleted != null) - { - _discoveryCompleted.Dispose(); - } + _discoveryCompleted.Dispose(); } // Indicate that object has been disposed _discoveryCompleted = null!; - _disposed = true; + _isDisposed = true; } } @@ -516,7 +506,7 @@ private void Dispose(bool disposing) /// /// If this request has been disposed. /// - private bool _disposed; + private bool _isDisposed; /// /// It get set when current discovery request is completed. diff --git a/src/Microsoft.TestPlatform.Client/Execution/TestRunRequest.cs b/src/Microsoft.TestPlatform.Client/Execution/TestRunRequest.cs index 5be9c1768d..0f2f9d19ee 100644 --- a/src/Microsoft.TestPlatform.Client/Execution/TestRunRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Execution/TestRunRequest.cs @@ -33,7 +33,7 @@ public class TestRunRequest : ITestRunRequest, IInternalTestRunEventsHandler /// /// Specifies whether the run is disposed or not /// - private bool _disposed; + private bool _isDisposed; /// /// Sync object for various operations @@ -108,7 +108,7 @@ public int ExecuteAsync() lock (_syncObject) { - if (_disposed) + if (_isDisposed) { throw new ObjectDisposedException("testRunRequest"); } @@ -186,7 +186,7 @@ public bool WaitForCompletion(int timeout) { EqtTrace.Verbose("TestRunRequest.WaitForCompletion: Waiting with timeout {0}.", timeout); - if (_disposed) + if (_isDisposed) { throw new ObjectDisposedException("testRunRequest"); } @@ -215,7 +215,7 @@ public void CancelAsync() lock (_cancelSyncObject) { - if (_disposed) + if (_isDisposed) { EqtTrace.Warning("Ignoring TestRunRequest.CancelAsync() as testRunRequest object has already been disposed."); return; @@ -244,7 +244,7 @@ public void Abort() lock (_cancelSyncObject) { - if (_disposed) + if (_isDisposed) { EqtTrace.Warning("Ignoring TestRunRequest.Abort() as testRunRequest object has already been disposed"); return; @@ -365,7 +365,7 @@ public void HandleTestRunComplete(TestRunCompleteEventArgs runCompleteArgs, Test lock (_syncObject) { // If this object is disposed, don't do anything - if (_disposed) + if (_isDisposed) { EqtTrace.Warning("TestRunRequest.TestRunComplete: Ignoring as the object is disposed."); return; @@ -481,7 +481,7 @@ public virtual void HandleTestRunStatsChange(TestRunChangedEventArgs? testRunCha lock (_syncObject) { // If this object is disposed, don't do anything - if (_disposed) + if (_isDisposed) { EqtTrace.Warning("TestRunRequest.SendTestRunStatsChange: Ignoring as the object is disposed."); return; @@ -506,7 +506,7 @@ public void HandleLogMessage(TestMessageLevel level, string? message) lock (_syncObject) { // If this object is disposed, don't do anything - if (_disposed) + if (_isDisposed) { EqtTrace.Warning("TestRunRequest.SendTestRunMessage: Ignoring as the object is disposed."); return; @@ -684,7 +684,7 @@ protected virtual void Dispose(bool disposing) lock (_syncObject) { - if (!_disposed) + if (!_isDisposed) { if (disposing) { @@ -693,7 +693,7 @@ protected virtual void Dispose(bool disposing) // Indicate that object has been disposed _runCompletionEvent = null!; - _disposed = true; + _isDisposed = true; } } diff --git a/src/Microsoft.TestPlatform.Common/DataCollection/DataCollectionManager.cs b/src/Microsoft.TestPlatform.Common/DataCollection/DataCollectionManager.cs index 1bf71927dc..5bdbe7fde1 100644 --- a/src/Microsoft.TestPlatform.Common/DataCollection/DataCollectionManager.cs +++ b/src/Microsoft.TestPlatform.Common/DataCollection/DataCollectionManager.cs @@ -55,7 +55,7 @@ internal class DataCollectionManager : IDataCollectionManager /// /// Specifies whether the object is disposed or not. /// - private bool _disposed; + private bool _isDisposed; /// /// Extension manager for data collectors. @@ -360,14 +360,14 @@ public Collection TestCaseEnded(TestCaseEndEventArgs testCaseEndE /// protected virtual void Dispose(bool disposing) { - if (!_disposed) + if (!_isDisposed) { if (disposing) { CleanupPlugins(); } - _disposed = true; + _isDisposed = true; } } diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/SocketTransport.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/SocketTransport.cs index 214327802f..c31a3f7c61 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/SocketTransport.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/SocketTransport.cs @@ -61,27 +61,21 @@ public bool WaitForConnection(int connectionTimeout) public void Dispose() { - Dispose(true); - } - - private void Dispose(bool disposing) - { - if (!_disposed) + if (_disposed) { - if (disposing) - { - if (_connectionInfo.Role == ConnectionRole.Client) - { - _communicationManager?.StopClient(); - } - else - { - _communicationManager?.StopServer(); - } - } + return; + } - _disposed = true; + if (_connectionInfo.Role == ConnectionRole.Client) + { + _communicationManager.StopClient(); } + else + { + _communicationManager.StopServer(); + } + + _disposed = true; } /// diff --git a/src/Microsoft.TestPlatform.CoreUtilities/PublicAPI/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.CoreUtilities/PublicAPI/PublicAPI.Shipped.txt index 01a58b8e25..d0ac422fda 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/PublicAPI/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.CoreUtilities/PublicAPI/PublicAPI.Shipped.txt @@ -86,6 +86,7 @@ Microsoft.VisualStudio.TestPlatform.Utilities.IOutput.Write(string? message, Mic Microsoft.VisualStudio.TestPlatform.Utilities.IOutput.WriteLine(string? message, Microsoft.VisualStudio.TestPlatform.Utilities.OutputLevel level) -> void Microsoft.VisualStudio.TestPlatform.Utilities.JobQueue Microsoft.VisualStudio.TestPlatform.Utilities.JobQueue.Dispose() -> void +virtual Microsoft.VisualStudio.TestPlatform.Utilities.JobQueue.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.Utilities.JobQueue.Flush() -> void Microsoft.VisualStudio.TestPlatform.Utilities.JobQueue.JobQueue(System.Action! processJob, string! displayName, int maxQueueLength, int maxQueueSize, bool enableBounds, System.Action! exceptionLogger) -> void Microsoft.VisualStudio.TestPlatform.Utilities.JobQueue.Pause() -> void diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Utilities/JobQueue.cs b/src/Microsoft.TestPlatform.CoreUtilities/Utilities/JobQueue.cs index 4661b79243..797591668c 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Utilities/JobQueue.cs +++ b/src/Microsoft.TestPlatform.CoreUtilities/Utilities/JobQueue.cs @@ -197,7 +197,14 @@ public void Flush() /// public void Dispose() { - if (_isDisposed) + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_isDisposed + || !disposing) { return; } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Adapter/FrameworkHandle.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Adapter/FrameworkHandle.cs index 6237da60fe..e90da7f031 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Adapter/FrameworkHandle.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Adapter/FrameworkHandle.cs @@ -117,9 +117,6 @@ public bool AttachDebuggerToProcess(int pid) public void Dispose() { Dispose(true); - - // Use SupressFinalize in case a subclass - // of this valueType implements a finalizer. GC.SuppressFinalize(this); } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/TestLoggerManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/TestLoggerManager.cs index b1a37b82ee..7a5aa16ca2 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/TestLoggerManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/TestLoggerManager.cs @@ -501,7 +501,7 @@ internal void EnableLogging() /// /// The disposing. /// - internal virtual void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) { if (!_isDisposed) { diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs index 55a3251627..c24ac37f0f 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs @@ -50,6 +50,7 @@ public class TestRequestHandler : ITestRequestHandler, IDeploymentAwareTestReque private Action? _onAttachDebuggerAckRecieved; private IPathConverter _pathConverter; private Exception? _messageProcessingUnrecoverableError; + private bool _isDisposed; public TestHostConnectionInfo ConnectionInfo { get; set; } string? IDeploymentAwareTestRequestHandler.LocalPath { get; set; } @@ -155,8 +156,22 @@ public void ProcessRequests(ITestHostManagerFactory testHostManagerFactory) /// public void Dispose() { - _communicationEndPoint?.Stop(); - _channel?.Dispose(); + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_isDisposed) + return; + + if (disposing) + { + _communicationEndPoint?.Stop(); + _channel?.Dispose(); + } + + _isDisposed = true; } /// diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/PublicAPI.Shipped.txt index 08831ed689..b2b5c873ef 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/PublicAPI.Shipped.txt @@ -6,6 +6,7 @@ Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler.Co Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler.ConnectionInfo.set -> void Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler.DiscoveryComplete(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs! discoveryCompleteEventArgs, System.Collections.Generic.IEnumerable? lastChunk) -> void Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler.Dispose() -> void +virtual Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler.LaunchProcessWithDebuggerAttached(Microsoft.VisualStudio.TestPlatform.ObjectModel.TestProcessStartInfo? testProcessStartInfo) -> int Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler.OnMessageReceived(object? sender, Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces.MessageReceivedEventArgs! messageReceivedArgs) -> void Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestHandler.ProcessRequests(Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.ITestHostManagerFactory! testHostManagerFactory) -> void diff --git a/src/Microsoft.TestPlatform.ObjectModel/Navigation/DiaSession.cs b/src/Microsoft.TestPlatform.ObjectModel/Navigation/DiaSession.cs index 9a7a27f3a2..cb02697e7b 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Navigation/DiaSession.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Navigation/DiaSession.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Diagnostics.CodeAnalysis; using System.IO; @@ -26,6 +27,8 @@ public class DiaSession : INavigationSession /// private readonly ISymbolReader _symbolReader; + private bool _isDisposed; + /// /// Initializes a new instance of the class. /// @@ -63,7 +66,21 @@ internal DiaSession(string binaryPath, string? searchPath, ISymbolReader symbolR /// public void Dispose() { - _symbolReader?.Dispose(); + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_isDisposed) + return; + + if (disposing) + { + _symbolReader.Dispose(); + } + + _isDisposed = true; } /// diff --git a/src/Microsoft.TestPlatform.ObjectModel/Navigation/FullSymbolReader.cs b/src/Microsoft.TestPlatform.ObjectModel/Navigation/FullSymbolReader.cs index 165d408413..111636a669 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Navigation/FullSymbolReader.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Navigation/FullSymbolReader.cs @@ -476,36 +476,38 @@ private static void ReleaseComObject(ref T? obj) } } - private void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) { - if (!_isDisposed) + if (_isDisposed) { - if (disposing) - { - foreach (Dictionary methodSymbolsForType in _methodSymbols.Values) - { - foreach (IDiaSymbol methodSymbol in methodSymbolsForType.Values) - { - IDiaSymbol? symToRelease = methodSymbol; - ReleaseComObject(ref symToRelease); - } - - methodSymbolsForType.Clear(); - } + return; + } - _methodSymbols.Clear(); - foreach (IDiaSymbol typeSymbol in _typeSymbols.Values) + if (disposing) + { + foreach (Dictionary methodSymbolsForType in _methodSymbols.Values) + { + foreach (IDiaSymbol methodSymbol in methodSymbolsForType.Values) { - IDiaSymbol? symToRelease = typeSymbol; + IDiaSymbol? symToRelease = methodSymbol; ReleaseComObject(ref symToRelease); } - _typeSymbols.Clear(); - ReleaseComObject(ref _session); - ReleaseComObject(ref _source); + methodSymbolsForType.Clear(); + } + + _methodSymbols.Clear(); + foreach (IDiaSymbol typeSymbol in _typeSymbols.Values) + { + IDiaSymbol? symToRelease = typeSymbol; + ReleaseComObject(ref symToRelease); } - _isDisposed = true; + _typeSymbols.Clear(); + ReleaseComObject(ref _session); + ReleaseComObject(ref _source); } + + _isDisposed = true; } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net/PublicAPI.Shipped.txt index 9178860c9e..39fb930c1f 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net/PublicAPI.Shipped.txt @@ -183,6 +183,7 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.DiaSession Microsoft.VisualStudio.TestPlatform.ObjectModel.DiaSession.DiaSession(string! binaryPath) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.DiaSession.DiaSession(string! binaryPath, string? searchPath) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.DiaSession.Dispose() -> void +virtual Microsoft.VisualStudio.TestPlatform.ObjectModel.DiaSession.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.DiaSession.GetNavigationData(string! declaringTypeName, string! methodName) -> Microsoft.VisualStudio.TestPlatform.ObjectModel.DiaNavigationData? Microsoft.VisualStudio.TestPlatform.ObjectModel.DiaSession.GetNavigationDataForMethod(string! declaringTypeName, string! methodName) -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Navigation.INavigationData? Microsoft.VisualStudio.TestPlatform.ObjectModel.InProcDataCollector.InProcDataCollection diff --git a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net462/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net462/PublicAPI.Shipped.txt index 4019bb762c..ac68aae3ff 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net462/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net462/PublicAPI.Shipped.txt @@ -4,6 +4,7 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.TestPlatformFormatExcept Microsoft.VisualStudio.TestPlatform.ObjectModel.SettingsException.SettingsException(System.Runtime.Serialization.SerializationInfo! info, System.Runtime.Serialization.StreamingContext context) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities.SuspendCodeCoverage Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities.SuspendCodeCoverage.Dispose() -> void +virtual Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities.SuspendCodeCoverage.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities.SuspendCodeCoverage.SuspendCodeCoverage() -> void override Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.TestPlatformFormatException.GetObjectData(System.Runtime.Serialization.SerializationInfo! info, System.Runtime.Serialization.StreamingContext context) -> void static Microsoft.VisualStudio.TestPlatform.ObjectModel.EqtTrace.SetupListener(System.Diagnostics.TraceListener? listener) -> void (forwarded, contained in Microsoft.TestPlatform.CoreUtilities) diff --git a/src/Microsoft.TestPlatform.ObjectModel/RegistryFreeActivationContext.cs b/src/Microsoft.TestPlatform.ObjectModel/RegistryFreeActivationContext.cs index 5c9a4ece6d..6ab0cd3b74 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/RegistryFreeActivationContext.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/RegistryFreeActivationContext.cs @@ -74,16 +74,18 @@ public void Dispose() protected virtual void Dispose(bool disposing) { - if (!_disposed) + if (_disposed) { - if (disposing) - { - // No managed resources to release - } + return; + } - DeactivateContext(); - _disposed = true; + if (disposing) + { + // No managed resources to release } + + DeactivateContext(); + _disposed = true; } /// diff --git a/src/Microsoft.TestPlatform.ObjectModel/Utilities/SuspendCodeCoverage.cs b/src/Microsoft.TestPlatform.ObjectModel/Utilities/SuspendCodeCoverage.cs index aa9bd91d86..1bcd046485 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Utilities/SuspendCodeCoverage.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Utilities/SuspendCodeCoverage.cs @@ -46,17 +46,19 @@ public void Dispose() /// Disposes instance. /// /// Should dispose. - internal void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) { - if (!_isDisposed) + if (_isDisposed) { - if (disposing) - { - Environment.SetEnvironmentVariable(SuspendCodeCoverageEnvVarName, _prevEnvValue, EnvironmentVariableTarget.Process); - } + return; + } - _isDisposed = true; + if (disposing) + { + Environment.SetEnvironmentVariable(SuspendCodeCoverageEnvVarName, _prevEnvValue, EnvironmentVariableTarget.Process); } + + _isDisposed = true; } } diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/PublicAPI.Shipped.txt index 0e3aafffc6..5fb1f3356d 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/PublicAPI.Shipped.txt @@ -77,6 +77,7 @@ Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyLoadCon Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.AssemblyResolve -> Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.AssemblyResolveEventHandler? Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.Dispose() -> void +virtual Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.PlatformAssemblyResolver() -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformEnvironment Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformEnvironment.Architecture.get -> Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformArchitecture diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/net462/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/net462/PublicAPI.Shipped.txt index 0d7e7074c9..c8d1f7b662 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/net462/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/net462/PublicAPI.Shipped.txt @@ -12,7 +12,6 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.RemoteEqtTrace.TraceLevel.get -> Microsoft.VisualStudio.TestPlatform.ObjectModel.RemoteEqtTrace.TraceLevel.set -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener.RollingFileTraceListener(string! fileName, string! name, int rollSizeKB) -> void -Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.~PlatformAssemblyResolver() -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformThread.Run(System.Action? action, Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformApartmentState apartmentState, bool waitForCompletion) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.ProcessHelper.LaunchProcess(string! processPath, string? arguments, string? workingDirectory, System.Collections.Generic.IDictionary? envVariables, System.Action? errorCallback, System.Action? exitCallBack, System.Action? outputCallBack) -> object! diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/net6.0/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/net6.0/PublicAPI.Shipped.txt index ba9b53b0b7..d17adb2a82 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/net6.0/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/net6.0/PublicAPI.Shipped.txt @@ -4,7 +4,6 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformEqtTrace.MapPlatformTrac Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformEqtTrace.WriteLine(Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformTraceLevel level, string? message) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener.RollingFileTraceListener(string! fileName, string! name, int rollSizeKB) -> void -Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.~PlatformAssemblyResolver() -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformThread.Run(System.Action? action, Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformApartmentState apartmentState, bool waitForCompletion) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.ProcessHelper.LaunchProcess(string! processPath, string? arguments, string? workingDirectory, System.Collections.Generic.IDictionary? envVariables, System.Action? errorCallback, System.Action? exitCallBack, System.Action? outputCallBack) -> object! diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netcoreapp1.0/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netcoreapp1.0/PublicAPI.Shipped.txt index ba9b53b0b7..d17adb2a82 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netcoreapp1.0/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netcoreapp1.0/PublicAPI.Shipped.txt @@ -4,7 +4,6 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformEqtTrace.MapPlatformTrac Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformEqtTrace.WriteLine(Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformTraceLevel level, string? message) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener.RollingFileTraceListener(string! fileName, string! name, int rollSizeKB) -> void -Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.~PlatformAssemblyResolver() -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformThread.Run(System.Action? action, Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformApartmentState apartmentState, bool waitForCompletion) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.ProcessHelper.LaunchProcess(string! processPath, string? arguments, string? workingDirectory, System.Collections.Generic.IDictionary? envVariables, System.Action? errorCallback, System.Action? exitCallBack, System.Action? outputCallBack) -> object! diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netcoreapp2.1/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netcoreapp2.1/PublicAPI.Shipped.txt index ba9b53b0b7..d17adb2a82 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netcoreapp2.1/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netcoreapp2.1/PublicAPI.Shipped.txt @@ -4,7 +4,6 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformEqtTrace.MapPlatformTrac Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformEqtTrace.WriteLine(Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformTraceLevel level, string? message) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener.RollingFileTraceListener(string! fileName, string! name, int rollSizeKB) -> void -Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.~PlatformAssemblyResolver() -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformThread.Run(System.Action? action, Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformApartmentState apartmentState, bool waitForCompletion) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.ProcessHelper.LaunchProcess(string! processPath, string? arguments, string? workingDirectory, System.Collections.Generic.IDictionary? envVariables, System.Action? errorCallback, System.Action? exitCallBack, System.Action? outputCallBack) -> object! diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt index ba9b53b0b7..d17adb2a82 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt @@ -4,7 +4,6 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformEqtTrace.MapPlatformTrac Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformEqtTrace.WriteLine(Microsoft.VisualStudio.TestPlatform.ObjectModel.PlatformTraceLevel level, string? message) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener Microsoft.VisualStudio.TestPlatform.ObjectModel.RollingFileTraceListener.RollingFileTraceListener(string! fileName, string! name, int rollSizeKB) -> void -Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.~PlatformAssemblyResolver() -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformThread.Run(System.Action? action, Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformApartmentState apartmentState, bool waitForCompletion) -> void Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.ProcessHelper.LaunchProcess(string! processPath, string? arguments, string? workingDirectory, System.Collections.Generic.IDictionary? envVariables, System.Action? errorCallback, System.Action? exitCallBack, System.Action? outputCallBack) -> object! diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/RollingFileTraceListener.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/RollingFileTraceListener.cs index 9406c5fad2..0364aee728 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/RollingFileTraceListener.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/RollingFileTraceListener.cs @@ -19,6 +19,7 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel; public class RollingFileTraceListener : TextWriterTraceListener { private readonly int _rollSizeInBytes; + private bool _isDisposed; /// /// Initializes a new instance of the class. @@ -89,9 +90,17 @@ internal static TallyKeepingFileStreamWriter OpenTextWriter(string fileName) /// protected override void Dispose(bool disposing) { - RollingHelper.Dispose(); + if (_isDisposed) + return; + + if (disposing) + { + RollingHelper.Dispose(); + } base.Dispose(disposing); + + _isDisposed = true; } private static Encoding GetEncodingWithFallback() @@ -310,17 +319,19 @@ private void SafeMove(string actualFileName, string archiveFileName, DateTime cu private void Dispose(bool disposing) { - if (!_disposed) + if (_disposed) + { + return; + } + + if (disposing && _managedWriter != null) { - if (disposing && _managedWriter != null) - { #if TODO - managedWriter.Close(); + managedWriter.Close(); #endif - } - - _disposed = true; } + + _disposed = true; } } diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/net462/Runtime/PlatformAssemblyResolver.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net462/Runtime/PlatformAssemblyResolver.cs index 5bbc4b89d0..4b581d0ef0 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/net462/Runtime/PlatformAssemblyResolver.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net462/Runtime/PlatformAssemblyResolver.cs @@ -16,7 +16,7 @@ public class PlatformAssemblyResolver : IAssemblyResolver /// /// Specifies whether the resolver is disposed or not /// - private bool _disposed; + private bool _isDisposed; /// /// Initializes a new instance of the class. @@ -37,23 +37,22 @@ public PlatformAssemblyResolver() public void Dispose() { Dispose(true); - - // Use SupressFinalize in case a subclass - // of this type implements a finalizer. GC.SuppressFinalize(this); } - protected void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) { - if (!_disposed) + if (_isDisposed) { - if (disposing) - { - AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolverEvent; - } + return; + } - _disposed = true; + if (disposing) + { + AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolverEvent; } + + _isDisposed = true; } /// diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/netcore/Runtime/PlatformAssemblyResolver.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/netcore/Runtime/PlatformAssemblyResolver.cs index 29a939d9c5..ff39358c97 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/netcore/Runtime/PlatformAssemblyResolver.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/netcore/Runtime/PlatformAssemblyResolver.cs @@ -39,23 +39,22 @@ public PlatformAssemblyResolver() public void Dispose() { Dispose(true); - - // Use SupressFinalize in case a subclass - // of this type implements a finalizer. GC.SuppressFinalize(this); } - protected void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) { - if (!_disposed) + if (_disposed) { - if (disposing) - { - AssemblyLoadContext.Default.Resolving -= AssemblyResolverEvent; - } + return; + } - _disposed = true; + if (disposing) + { + AssemblyLoadContext.Default.Resolving -= AssemblyResolverEvent; } + + _disposed = true; } /// diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard/Runtime/PlatformAssemblyResolver.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard/Runtime/PlatformAssemblyResolver.cs index 0708b2214a..a1f033b5dc 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard/Runtime/PlatformAssemblyResolver.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard/Runtime/PlatformAssemblyResolver.cs @@ -21,6 +21,12 @@ public PlatformAssemblyResolver() public event AssemblyResolveEventHandler? AssemblyResolve; public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) { throw new NotImplementedException(); } diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/Runtime/PlatformAssemblyResolver.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/Runtime/PlatformAssemblyResolver.cs index 201589cf88..b2a4c3aa0f 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/Runtime/PlatformAssemblyResolver.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/Runtime/PlatformAssemblyResolver.cs @@ -3,6 +3,8 @@ #if WINDOWS_UWP +using System; + using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces; namespace Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; @@ -18,6 +20,12 @@ public PlatformAssemblyResolver() public event AssemblyResolveEventHandler? AssemblyResolve; public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) { } diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/TestSession.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/TestSession.cs index aea930c533..c14a8d7205 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/TestSession.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/TestSession.cs @@ -73,7 +73,11 @@ protected virtual void Dispose(bool disposing) return; } - StopTestSession(); + if (disposing) + { + StopTestSession(); + } + _disposed = true; } diff --git a/src/vstest.console/PublicAPI/PublicAPI.Shipped.txt b/src/vstest.console/PublicAPI/PublicAPI.Shipped.txt index 41ccf07058..6e73611cbf 100644 --- a/src/vstest.console/PublicAPI/PublicAPI.Shipped.txt +++ b/src/vstest.console/PublicAPI/PublicAPI.Shipped.txt @@ -16,10 +16,12 @@ Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.MetricsPublisherFactor Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.MetricsPublisherFactory.MetricsPublisherFactory() -> void Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.NoOpMetricsPublisher Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.NoOpMetricsPublisher.Dispose() -> void +virtual Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.NoOpMetricsPublisher.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.NoOpMetricsPublisher.NoOpMetricsPublisher() -> void Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.NoOpMetricsPublisher.PublishMetrics(string! eventName, System.Collections.Generic.IDictionary! metrics) -> void Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.TextFileTelemetryPublisher Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.TextFileTelemetryPublisher.Dispose() -> void +virtual Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.TextFileTelemetryPublisher.Dispose(bool disposing) -> void Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.TextFileTelemetryPublisher.PublishMetrics(string! eventName, System.Collections.Generic.IDictionary! metrics) -> void Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher.TextFileTelemetryPublisher.TextFileTelemetryPublisher() -> void Microsoft.VisualStudio.TestPlatform.CommandLine.TestSourceException diff --git a/src/vstest.console/Publisher/NoOpMetricsPublisher.cs b/src/vstest.console/Publisher/NoOpMetricsPublisher.cs index dede6ede60..f9d6cffad5 100644 --- a/src/vstest.console/Publisher/NoOpMetricsPublisher.cs +++ b/src/vstest.console/Publisher/NoOpMetricsPublisher.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Collections.Generic; namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Publisher; @@ -24,6 +25,12 @@ public void PublishMetrics(string eventName, IDictionary metric /// Will do NO-OP /// public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) { // No operation } diff --git a/src/vstest.console/Publisher/TextFileTelemetryPublisher.cs b/src/vstest.console/Publisher/TextFileTelemetryPublisher.cs index 36b287c52f..8554578b96 100644 --- a/src/vstest.console/Publisher/TextFileTelemetryPublisher.cs +++ b/src/vstest.console/Publisher/TextFileTelemetryPublisher.cs @@ -32,6 +32,12 @@ public void PublishMetrics(string eventName, IDictionary metric /// Will do NO-OP /// public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) { // No operation } diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index ddc2657144..458538e27c 100644 --- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -633,23 +633,22 @@ public void CancelTestRunAttachmentsProcessing() public void Dispose() { Dispose(true); - - // Use SupressFinalize in case a subclass - // of this type implements a finalizer. GC.SuppressFinalize(this); } - private void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) { - if (!_isDisposed) + if (_isDisposed) { - if (disposing) - { - _metricsPublisher.Result.Dispose(); - } + return; + } - _isDisposed = true; + if (disposing) + { + _metricsPublisher.Result.Dispose(); } + + _isDisposed = true; } private bool UpdateRunSettingsIfRequired( diff --git a/test/Microsoft.TestPlatform.PerformanceTests/PerfInstrumentation/PerfAnalyzer.cs b/test/Microsoft.TestPlatform.PerformanceTests/PerfInstrumentation/PerfAnalyzer.cs index d15664014c..678ce68aae 100644 --- a/test/Microsoft.TestPlatform.PerformanceTests/PerfInstrumentation/PerfAnalyzer.cs +++ b/test/Microsoft.TestPlatform.PerformanceTests/PerfInstrumentation/PerfAnalyzer.cs @@ -245,6 +245,7 @@ private static IDictionary GetPayloadProperties(TraceEvent data) public class PerfTracker : IDisposable { private readonly PerfAnalyzer _perfAnalyzer; + private bool _isDisposed; public PerfTracker(PerfAnalyzer perfAnalyzer) { @@ -254,8 +255,22 @@ public PerfTracker(PerfAnalyzer perfAnalyzer) public void Dispose() { - _perfAnalyzer.DisableProvider(); - _perfAnalyzer.AnalyzeEventsData(); + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_isDisposed) + return; + + if (disposing) + { + _perfAnalyzer.DisableProvider(); + _perfAnalyzer.AnalyzeEventsData(); + } + + _isDisposed = true; } } } diff --git a/test/Microsoft.TestPlatform.TestUtilities/TempDirectory.cs b/test/Microsoft.TestPlatform.TestUtilities/TempDirectory.cs index e041dff55e..d81248bc6a 100644 --- a/test/Microsoft.TestPlatform.TestUtilities/TempDirectory.cs +++ b/test/Microsoft.TestPlatform.TestUtilities/TempDirectory.cs @@ -11,6 +11,8 @@ namespace Microsoft.TestPlatform.TestUtilities; public class TempDirectory : IDisposable { + private bool _isDisposed; + /// /// Creates a unique temporary directory. /// @@ -23,7 +25,21 @@ public TempDirectory() public void Dispose() { - TryRemoveDirectory(Path); + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_isDisposed) + return; + + if (disposing) + { + TryRemoveDirectory(Path); + } + + _isDisposed = true; } public DirectoryInfo CreateDirectory(string dir)