From 6d3d1512ad3d5c778d11fbc6c84a1325d3f1b4d9 Mon Sep 17 00:00:00 2001 From: Encryptor Date: Sat, 12 Nov 2016 18:48:26 +0300 Subject: [PATCH] + Fixed a bug in cancellinig tasks when a group of items were added at once + #v0.0.0.2 is ready --- RudeFox.FrontEnd/Properties/AssemblyInfo.cs | 4 +- RudeFox.FrontEnd/Services/ShredderService.cs | 20 +++++++ RudeFox.FrontEnd/ViewModels/MainWindowVM.cs | 58 ++++++++++++++------ RudeFox.FrontEnd/ViewModels/WorkItemVM.cs | 9 +++ 4 files changed, 72 insertions(+), 19 deletions(-) diff --git a/RudeFox.FrontEnd/Properties/AssemblyInfo.cs b/RudeFox.FrontEnd/Properties/AssemblyInfo.cs index daa4b14..b308a33 100644 --- a/RudeFox.FrontEnd/Properties/AssemblyInfo.cs +++ b/RudeFox.FrontEnd/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.0.0.1")] -[assembly: AssemblyFileVersion("0.0.0.1")] +[assembly: AssemblyVersion("0.0.0.2")] +[assembly: AssemblyFileVersion("0.0.0.2")] diff --git a/RudeFox.FrontEnd/Services/ShredderService.cs b/RudeFox.FrontEnd/Services/ShredderService.cs index aef6cdd..e244c86 100644 --- a/RudeFox.FrontEnd/Services/ShredderService.cs +++ b/RudeFox.FrontEnd/Services/ShredderService.cs @@ -208,6 +208,26 @@ await Task.Run(() => return true; } + + public bool IsFileLocked(FileInfo file) + { + FileStream stream = null; + + try + { + stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None); + } + catch (IOException) + { + return true; + } + finally + { + if (stream != null) stream.Close(); + } + + return false; + } #endregion } } diff --git a/RudeFox.FrontEnd/ViewModels/MainWindowVM.cs b/RudeFox.FrontEnd/ViewModels/MainWindowVM.cs index f40bd00..7dde8ef 100644 --- a/RudeFox.FrontEnd/ViewModels/MainWindowVM.cs +++ b/RudeFox.FrontEnd/ViewModels/MainWindowVM.cs @@ -66,19 +66,19 @@ void IDropTarget.Drop(IDropInfo dropInfo) if (data.GetDataPresent(DataFormats.FileDrop)) { string[] paths = (string[])data.GetData(DataFormats.FileDrop); - DeleteItems(paths); + DeleteItems(paths.ToList()); } } #endregion #region Methods - private async void DeleteItems(string[] paths) + private async void DeleteItems(List paths) { string message; - if (paths.Length == 1) + if (paths.Count == 1) message = "Are you sure you want to delete this item?"; else - message = $"Are you sure you want to delete {paths.Length} items?"; + message = $"Are you sure you want to delete {paths.Count} items?"; var response = MessageBox.Show(message, "Deleting items", MessageBoxButton.YesNo, MessageBoxImage.Exclamation); if (response != MessageBoxResult.Yes) return; @@ -86,6 +86,12 @@ private async void DeleteItems(string[] paths) var newItems = new List(); var cts = new CancellationTokenSource(); + var duplicates = from i in WorkItems + join p in paths + on i.Path equals p + select p; + paths.RemoveAll(p => duplicates.Contains(p)); + foreach (var path in paths) { var item = new WorkItemVM(); @@ -93,6 +99,11 @@ private async void DeleteItems(string[] paths) if (File.Exists(path)) { + if (ShredderService.Instance.IsFileLocked(new FileInfo(path))) + { + MessageBox.Show($"Can't access file, it's being used by another application: {path}"); + continue; + } item.Type = ItemType.File; newItems.Add(item); } @@ -105,29 +116,42 @@ private async void DeleteItems(string[] paths) item.DeleteRequested += (sender, canceled) => { - if (canceled) cts.Cancel(); WorkItems.Remove(sender as WorkItemVM); sender = null; }; + item.CancellationTokenSource = new CancellationTokenSource(); WorkItems.Add(item); } - foreach (var item in newItems) + var tasks = newItems.Select(item => { - try - { - var progress = new Progress(); - progress.ProgressChanged += (sender, percent) => - { - item.Progress = percent * 100; - }; - await ShredderService.Instance.ShredItemAsync(item.Path, cts.Token, progress); - } - catch (OperationCanceledException) - { + return ShredderService.Instance.ShredItemAsync(item.Path, item.CancellationTokenSource.Token, item.TaskProgress); + }); + try + { + await Task.WhenAll(tasks); + } + catch (OperationCanceledException) + { + + } + catch (AggregateException exc) + { + var msg = $"{exc.InnerExceptions.Count()} error(s) occured: "; + foreach(var ex in exc.InnerExceptions) + { + msg += "\n---------------------------"; + msg += Environment.NewLine; + msg += ex.ToString(); } + MessageBox.Show(msg); + } + catch( Exception exc) + { + var failed = tasks.Where(t => t.IsFaulted); + MessageBox.Show(exc.ToString()); } } #endregion diff --git a/RudeFox.FrontEnd/ViewModels/WorkItemVM.cs b/RudeFox.FrontEnd/ViewModels/WorkItemVM.cs index 0bd7c43..ebf6508 100644 --- a/RudeFox.FrontEnd/ViewModels/WorkItemVM.cs +++ b/RudeFox.FrontEnd/ViewModels/WorkItemVM.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Windows.Input; @@ -21,6 +22,9 @@ public WorkItemVM() { OnDeleteRequested(true); }); + CancellationTokenSource = new CancellationTokenSource(); + TaskProgress = new Progress(); + TaskProgress.ProgressChanged += (sender, percent) => Progress = percent * 100; } #endregion @@ -111,6 +115,10 @@ public string Size } } } + + public CancellationTokenSource CancellationTokenSource { get; set; } + public Progress TaskProgress { get; set; } + #endregion #region Events @@ -133,6 +141,7 @@ private void OnDeleteRequested(bool canceled = false) { var handler = DeleteRequested; handler?.Invoke(this, canceled); + if (canceled) CancellationTokenSource.Cancel(); } #endregion }