fix memory leak and set object to null when switching viewer target

This commit is contained in:
Paddy Xu
2017-05-17 21:55:30 +03:00
parent 410411692e
commit 482325a479
11 changed files with 66 additions and 24 deletions

View File

@@ -127,6 +127,9 @@ namespace QuickLook.Plugin.ArchiveViewer
private string[] GetPathFragments(string path) private string[] GetPathFragments(string path)
{ {
if (string.IsNullOrEmpty(path))
return new string[0];
var frags = path.Split('\\', '/').Where(f => !string.IsNullOrEmpty(f)).ToArray(); var frags = path.Split('\\', '/').Where(f => !string.IsNullOrEmpty(f)).ToArray();
return frags.Select((s, i) => frags.Take(i + 1).Aggregate((a, b) => a + "\\" + b)).ToArray(); return frags.Select((s, i) => frags.Take(i + 1).Aggregate((a, b) => a + "\\" + b)).ToArray();

View File

@@ -16,18 +16,18 @@ namespace QuickLook.Plugin.ArchiveViewer
if (Directory.Exists(path)) if (Directory.Exists(path))
return false; return false;
using (var stream = File.OpenRead(path)) switch (Path.GetExtension(path).ToLower())
{ {
try case ".zip":
{ case ".rar":
ArchiveFactory.Open(stream); case ".7z":
} case ".gz":
catch (Exception) case ".tar":
{ return true;
default:
return false; return false;
}
} }
return true;
} }
public void Prepare(string path, ContextObject context) public void Prepare(string path, ContextObject context)
@@ -50,6 +50,7 @@ namespace QuickLook.Plugin.ArchiveViewer
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
_panel?.Dispose(); _panel?.Dispose();
_panel = null;
} }
~Plugin() ~Plugin()

View File

@@ -48,6 +48,7 @@ namespace QuickLook.Plugin.HtmlViewer
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
_panel?.Dispose(); _panel?.Dispose();
_panel = null;
} }
~Plugin() ~Plugin()

View File

@@ -52,6 +52,7 @@ namespace QuickLook.Plugin.ImageViewer
public void Cleanup() public void Cleanup()
{ {
_ip = null;
} }
} }
} }

View File

@@ -49,6 +49,7 @@ namespace QuickLook.Plugin.MarkdownViewer
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
_panel?.Dispose(); _panel?.Dispose();
_panel = null;
} }
~Plugin() ~Plugin()

View File

@@ -58,6 +58,7 @@ namespace QuickLook.Plugin.TextViewer
public void Cleanup() public void Cleanup()
{ {
_tvp = null;
} }
} }
} }

View File

@@ -55,6 +55,7 @@ namespace QuickLook.Plugin.VideoViewer
public void Cleanup() public void Cleanup()
{ {
_vp?.Dispose(); _vp?.Dispose();
_vp = null;
} }
} }
} }

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using FontAwesome.WPF; using FontAwesome.WPF;
@@ -51,11 +52,16 @@ namespace QuickLook.Plugin.VideoViewer
: FontAwesomeIcon.PlayCircleOutline; : FontAwesomeIcon.PlayCircleOutline;
} }
[DebuggerNonUserCode]
private void ShowErrorNotification(object sender, MediaErrorRoutedEventArgs e) private void ShowErrorNotification(object sender, MediaErrorRoutedEventArgs e)
{ {
_context.ShowNotification("", "An error occurred while loading the video.");
mediaElement.Stop(); mediaElement.Stop();
_context.ShowNotification("", "An error occurred while loading the video."); Dispose();
throw new Exception("fallback to default viewer.");
} }
public void LoadAndPlay(string path) public void LoadAndPlay(string path)

View File

@@ -95,15 +95,20 @@ namespace QuickLook
this.MoveWindow(newLeft, newTop, size.Width, size.Height); this.MoveWindow(newLeft, newTop, size.Width, size.Height);
} }
internal void UnloadPlugin()
{
container.Content = null;
// clean up plugin and refresh ContextObject for next use
ContextObject.ViewerPlugin?.Cleanup();
}
private new void Hide() private new void Hide()
{ {
if (App.RunningAsViewer) if (App.RunningAsViewer)
Application.Current.Shutdown(); Application.Current.Shutdown();
container.Content = null; UnloadPlugin();
// clean up plugin and refresh ContextObject for next use
ContextObject.ViewerPlugin?.Cleanup();
ContextObject.Reset(); ContextObject.Reset();
GC.Collect(); GC.Collect();
@@ -111,8 +116,9 @@ namespace QuickLook
// revert UI changes // revert UI changes
ContextObject.IsBusy = true; ContextObject.IsBusy = true;
Left -= 10000; base.Hide();
Dispatcher.Delay(100, _ => base.Hide()); //Left -= 10000;
//Dispatcher.Delay(100, _ => base.Hide());
} }
internal void BeginShow(IViewer matchedPlugin, string path) internal void BeginShow(IViewer matchedPlugin, string path)
@@ -121,13 +127,27 @@ namespace QuickLook
ContextObject.ViewerPlugin = matchedPlugin; ContextObject.ViewerPlugin = matchedPlugin;
// get window size before showing it // get window size before showing it
matchedPlugin.Prepare(path, ContextObject); ContextObject.ViewerPlugin.Prepare(path, ContextObject);
Show(); Show();
// load plugin, do not block UI // load plugin, do not block UI
Dispatcher.BeginInvoke(new Action(() => matchedPlugin.View(path, ContextObject)), Exception thrown = null;
DispatcherPriority.Render); Dispatcher.BeginInvoke(new Action(() =>
{
try
{
ContextObject.ViewerPlugin.View(path, ContextObject);
}
catch (Exception e)
{
thrown = e;
}
}),
DispatcherPriority.Render).Wait();
if (thrown != null)
throw thrown;
} }
internal bool BeginHide() internal bool BeginHide()

View File

@@ -15,24 +15,28 @@ namespace QuickLook.Plugin.InfoPanel
public void Prepare(string path, ContextObject context) public void Prepare(string path, ContextObject context)
{ {
_ip = new InfoPanel(); context.PreferredSize = new Size {Width = 453, Height = 172};
context.CanResize = false;
context.PreferredSize = new Size {Width = _ip.Width, Height = _ip.Height};
} }
public void View(string path, ContextObject context) public void View(string path, ContextObject context)
{ {
_ip.DisplayInfo(path); _ip = new InfoPanel();
context.ViewerContent = _ip; context.ViewerContent = _ip;
context.CanResize = false;
_ip.DisplayInfo(path);
context.IsBusy = false; context.IsBusy = false;
} }
public void Cleanup() public void Cleanup()
{ {
if (_ip == null)
return;
_ip.Stop = true; _ip.Stop = true;
_ip = null;
} }
} }
} }

View File

@@ -53,12 +53,15 @@ namespace QuickLook
{ {
try try
{ {
_viewWindow.UnloadPlugin();
_viewWindow.BeginShow(matchedPlugin, path); _viewWindow.BeginShow(matchedPlugin, path);
} }
catch (Exception e) // if current plugin failed, switch to default one. catch (Exception e) // if current plugin failed, switch to default one.
{ {
_viewWindow.BeginHide(); _viewWindow.BeginHide();
TrayIconManager.GetInstance().ShowNotification("", $"Failed to preview {Path.GetFileName(path)}", true);
Debug.WriteLine(e.ToString()); Debug.WriteLine(e.ToString());
Debug.WriteLine(e.StackTrace); Debug.WriteLine(e.StackTrace);