diff --git a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs index 09b5fbd74c..c4958ee3ea 100644 --- a/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs +++ b/src/Microsoft.ML.TensorFlow/TensorflowTransform.cs @@ -452,7 +452,7 @@ public void Dispose() try { - if (Session != null && Session.graph != IntPtr.Zero) + if (Session?.graph != IntPtr.Zero) { Session.graph.Dispose(); } diff --git a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs index c833ad0b9a..322de8b5e6 100644 --- a/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs +++ b/src/Microsoft.ML.Vision/ImageClassificationTrainer.cs @@ -77,8 +77,10 @@ namespace Microsoft.ML.Vision /// public sealed class ImageClassificationTrainer : TrainerEstimatorBase, - ImageClassificationModelParameters> + ImageClassificationModelParameters>, IDisposable { + private bool _isDisposed; + internal const string LoadName = "ImageClassificationTrainer"; internal const string UserName = "Image Classification Trainer"; internal const string ShortName = "IMGCLSS"; @@ -1301,26 +1303,22 @@ private static TensorFlowSessionWrapper LoadTensorFlowSessionFromMetaGraph(IHost return new TensorFlowSessionWrapper(GetSession(env, modelFilePath, true), modelFilePath); } - ~ImageClassificationTrainer() + public void Dispose() { - Dispose(false); - } + if (_isDisposed) + return; - private void Dispose(bool disposing) - { - // Ensure that the Session is not null and its handle is not Zero, as it may have already been - // disposed/finalized. Technically we shouldn't be calling this if disposing == false, - // since we're running in finalizer and the GC doesn't guarantee ordering of finalization of managed - // objects, but we have to make sure that the Session is closed before deleting our temporary directory. - if (_session != null && _session != IntPtr.Zero) + if (_session?.graph != IntPtr.Zero) { - _session.close(); + _session.graph.Dispose(); } - if (_session != null && _session.graph != IntPtr.Zero) + if (_session != null && _session != IntPtr.Zero) { - _session.graph.Dispose(); + _session.close(); } + + _isDisposed = true; } /// @@ -1337,8 +1335,10 @@ private void Dispose(bool disposing) /// Image Classification predictor. This class encapsulates the trained Deep Neural Network(DNN) model /// and is used to score images. /// - public sealed class ImageClassificationModelParameters : ModelParametersBase>, IValueMapper + public sealed class ImageClassificationModelParameters : ModelParametersBase>, IValueMapper, IDisposable { + private bool _isDisposed; + internal const string LoaderSignature = "ImageClassificationPred"; private static VersionInfo GetVersionInfo() { @@ -1490,26 +1490,22 @@ public void Score(in VBuffer image, Span classProbabilities) return (ValueMapper)(Delegate)del; } - ~ImageClassificationModelParameters() + public void Dispose() { - Dispose(false); - } + if (_isDisposed) + return; - private void Dispose(bool disposing) - { - // Ensure that the Session is not null and its handle is not Zero, as it may have already been - // disposed/finalized. Technically we shouldn't be calling this if disposing == false, - // since we're running in finalizer and the GC doesn't guarantee ordering of finalization of managed - // objects, but we have to make sure that the Session is closed before deleting our temporary directory. - if (_session != null && _session != IntPtr.Zero) + if (_session?.graph != IntPtr.Zero) { - _session.close(); + _session.graph.Dispose(); } - if (_session != null && _session.graph != IntPtr.Zero) + if (_session != null && _session != IntPtr.Zero) { - _session.graph.Dispose(); + _session.close(); } + + _isDisposed = true; } } }