From 16a6d1a928b303f5536649744fdbf7875471b7fd Mon Sep 17 00:00:00 2001 From: sr55 Date: Sat, 2 Feb 2019 10:56:34 +0000 Subject: [PATCH] WinGui: Make the disposal of services more aggressive. May Fix or help in #1851 --- .../HandBrakeWPF/Services/Encode/LibEncode.cs | 19 +++- .../Services/PrePostActionService.cs | 21 ++-- .../Services/Scan/Interfaces/IScan.cs | 2 +- win/CS/HandBrakeWPF/Services/Scan/LibScan.cs | 106 ++++++++++++------ 4 files changed, 98 insertions(+), 50 deletions(-) diff --git a/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs b/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs index 382dd7cf9..ca4100b62 100644 --- a/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs +++ b/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs @@ -143,6 +143,10 @@ namespace HandBrakeWPF.Services.Encode if (this.instance != null) { this.instance.StopEncode(); + this.instance.EncodeCompleted -= this.InstanceEncodeCompleted; + this.instance.EncodeProgress -= this.InstanceEncodeProgress; + this.instance.Dispose(); + this.instance = null; this.ServiceLogMessage("Encode Stopped"); } } @@ -209,11 +213,24 @@ namespace HandBrakeWPF.Services.Encode string hbLog = this.ProcessLogs(this.currentTask.Destination, this.isPreviewInstance, this.currentConfiguration); long filesize = this.GetFilesize(this.currentTask.Destination); - // Raise the Encode Completed EVent. + // Raise the Encode Completed Event. this.InvokeEncodeCompleted( e.Error ? new EventArgs.EncodeCompletedEventArgs(false, null, string.Empty, this.currentTask.Destination, hbLog, filesize) : new EventArgs.EncodeCompletedEventArgs(true, null, string.Empty, this.currentTask.Destination, hbLog, filesize)); + + // Cleanup + try + { + this.instance.EncodeCompleted -= this.InstanceEncodeCompleted; + this.instance.EncodeProgress -= this.InstanceEncodeProgress; + this.instance.Dispose(); + this.instance = null; + } + catch (Exception exc) + { + this.ServiceLogMessage("Failed to cleanup Encode instance: " + exc ); + } } private long GetFilesize(string destination) diff --git a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs index b11c814ba..4cbd4c82a 100644 --- a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs +++ b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs @@ -20,9 +20,11 @@ namespace HandBrakeWPF.Services using HandBrake.Interop.Utilities; using HandBrakeWPF.EventArgs; + using HandBrakeWPF.Instance; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.Services.Queue.Interfaces; + using HandBrakeWPF.Services.Scan.Interfaces; using HandBrakeWPF.Utilities; using HandBrakeWPF.ViewModels.Interfaces; @@ -34,20 +36,10 @@ namespace HandBrakeWPF.Services /// public class PrePostActionService : IPrePostActionService { - /// - /// The queue processor. - /// private readonly IQueueProcessor queueProcessor; - - /// - /// The user setting service. - /// private readonly IUserSettingService userSettingService; - - /// - /// The window manager. - /// private readonly IWindowManager windowManager; + private readonly IScan scanService; /// /// Initializes a new instance of the class. @@ -61,11 +53,12 @@ namespace HandBrakeWPF.Services /// /// The window Manager. /// - public PrePostActionService(IQueueProcessor queueProcessor, IUserSettingService userSettingService, IWindowManager windowManager) + public PrePostActionService(IQueueProcessor queueProcessor, IUserSettingService userSettingService, IWindowManager windowManager, IScan scanService) { this.queueProcessor = queueProcessor; this.userSettingService = userSettingService; this.windowManager = windowManager; + this.scanService = scanService; this.queueProcessor.QueueCompleted += QueueProcessorQueueCompleted; this.queueProcessor.EncodeService.EncodeCompleted += EncodeService_EncodeCompleted; @@ -157,7 +150,7 @@ namespace HandBrakeWPF.Services }); if (!titleSpecificView.IsCancelled) - { + { // Do something when the encode ends. switch (this.userSettingService.GetUserSetting(UserSettingConstants.WhenCompleteAction)) { @@ -166,9 +159,11 @@ namespace HandBrakeWPF.Services ProcessStartInfo shutdown = new ProcessStartInfo("Shutdown", "-s -t 60"); shutdown.UseShellExecute = false; Process.Start(shutdown); + Execute.OnUIThread(() => System.Windows.Application.Current.Shutdown()); break; case "Log off": case "Ausloggen": + this.scanService.Dispose(); Win32.ExitWindowsEx(0, 0); break; case "Suspend": diff --git a/win/CS/HandBrakeWPF/Services/Scan/Interfaces/IScan.cs b/win/CS/HandBrakeWPF/Services/Scan/Interfaces/IScan.cs index 5458b9d2d..61e34ddb4 100644 --- a/win/CS/HandBrakeWPF/Services/Scan/Interfaces/IScan.cs +++ b/win/CS/HandBrakeWPF/Services/Scan/Interfaces/IScan.cs @@ -43,7 +43,7 @@ namespace HandBrakeWPF.Services.Scan.Interfaces /// /// The IScan Interface /// - public interface IScan + public interface IScan : IDisposable { /// /// Scan has Started diff --git a/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs b/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs index 40823f3f7..de26ae87d 100644 --- a/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs +++ b/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs @@ -15,7 +15,6 @@ namespace HandBrakeWPF.Services.Scan using System.Windows.Media.Imaging; using HandBrake.Interop.Interop; - using HandBrake.Interop.Interop.HbLib; using HandBrake.Interop.Interop.Interfaces; using HandBrake.Interop.Interop.Json.Scan; using HandBrake.Interop.Interop.Model; @@ -25,26 +24,23 @@ namespace HandBrakeWPF.Services.Scan using HandBrakeWPF.Instance; using HandBrakeWPF.Services.Encode.Model; - using HandBrakeWPF.Services.Encode.Model.Models; using HandBrakeWPF.Services.Scan.EventArgs; using HandBrakeWPF.Services.Scan.Factories; using HandBrakeWPF.Services.Scan.Interfaces; using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.Utilities; - using Chapter = Model.Chapter; using ILog = Logging.Interfaces.ILog; using LogLevel = Logging.Model.LogLevel; using LogMessageType = Logging.Model.LogMessageType; using LogService = Logging.LogService; using ScanProgressEventArgs = HandBrake.Interop.Interop.EventArgs.ScanProgressEventArgs; - using Subtitle = Model.Subtitle; using Title = Model.Title; /// /// Scan a Source /// - public class LibScan : IScan + public class LibScan : IScan, IDisposable { #region Private Variables @@ -149,7 +145,16 @@ namespace HandBrakeWPF.Services.Scan { this.ServiceLogMessage("Manually Stopping Scan ..."); this.IsScanning = false; - this.instance.StopScan(); + + var handBrakeInstance = this.instance; + if (handBrakeInstance != null) + { + handBrakeInstance.StopScan(); + handBrakeInstance.ScanProgress -= this.InstanceScanProgress; + handBrakeInstance.ScanCompleted -= this.InstanceScanCompleted; + handBrakeInstance.Dispose(); + this.instance = null; + } } catch (Exception exc) { @@ -158,6 +163,7 @@ namespace HandBrakeWPF.Services.Scan finally { this.ScanCompleted?.Invoke(this, new ScanCompletedEventArgs(this.isCancelled, null, null, null)); + this.instance = null; this.ServiceLogMessage("Scan Stopped ..."); } } @@ -250,7 +256,7 @@ namespace HandBrakeWPF.Services.Scan /// The preview Count. /// /// - /// The configuraiton. + /// The configuration. /// private void ScanSource(object sourcePath, int title, int previewCount, HBConfiguration configuraiton) { @@ -293,44 +299,58 @@ namespace HandBrakeWPF.Services.Scan /// private void InstanceScanCompleted(object sender, System.EventArgs e) { - this.ServiceLogMessage("Processing Scan Information ..."); - bool cancelled = this.isCancelled; - this.isCancelled = false; - - // TODO -> Might be a better place to fix this. - string path = this.currentSourceScanPath; - if (this.currentSourceScanPath.Contains("\"")) + try { - path = this.currentSourceScanPath.Trim('\"'); - } + this.ServiceLogMessage("Processing Scan Information ..."); + bool cancelled = this.isCancelled; + this.isCancelled = false; - // Process into internal structures. - Source sourceData = null; - if (this.instance?.Titles != null) - { - sourceData = new Source { Titles = ConvertTitles(this.instance.Titles), ScanPath = path }; - } + // TODO -> Might be a better place to fix this. + string path = this.currentSourceScanPath; + if (this.currentSourceScanPath.Contains("\"")) + { + path = this.currentSourceScanPath.Trim('\"'); + } - this.IsScanning = false; + // Process into internal structures. + Source sourceData = null; + if (this.instance?.Titles != null) + { + sourceData = new Source { Titles = this.ConvertTitles(this.instance.Titles), ScanPath = path }; + } - if (this.postScanOperation != null) - { - try + this.IsScanning = false; + + if (this.postScanOperation != null) { - this.postScanOperation(true, sourceData); + try + { + this.postScanOperation(true, sourceData); + } + catch (Exception exc) + { + Debug.WriteLine(exc); + } + + this.postScanOperation = null; // Reset + this.ServiceLogMessage("Scan Finished for Queue Edit ..."); } - catch (Exception exc) + else { - Debug.WriteLine(exc); + this.ScanCompleted?.Invoke( + this, + new ScanCompletedEventArgs(cancelled, null, string.Empty, sourceData)); + this.ServiceLogMessage("Scan Finished ..."); } - - this.postScanOperation = null; // Reset - this.ServiceLogMessage("Scan Finished for Queue Edit ..."); } - else + finally { - this.ScanCompleted?.Invoke(this, new ScanCompletedEventArgs(cancelled, null, string.Empty, sourceData)); - this.ServiceLogMessage("Scan Finished ..."); + var handBrakeInstance = this.instance; + if (handBrakeInstance != null) + { + handBrakeInstance.ScanProgress -= this.InstanceScanProgress; + handBrakeInstance.ScanCompleted -= this.InstanceScanCompleted; + } } } @@ -380,5 +400,21 @@ namespace HandBrakeWPF.Services.Scan return titleList; } #endregion + + public void Dispose() + { + if (this.instance != null) + { + try + { + this.instance.Dispose(); + this.instance = null; + } + catch (Exception e) + { + this.ServiceLogMessage("Unable to Dispose of LibScan: " + e); + } + } + } } } \ No newline at end of file -- 2.40.0