ProgressViewModel.cs
1 #pragma warning disable IDE0073 2 // Copyright (c) Brice Lambson 3 // The Brice Lambson licenses this file to you under the MIT license. 4 // See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/ 5 #pragma warning restore IDE0073 6 7 using System; 8 using System.Diagnostics; 9 using System.Linq; 10 using System.Threading; 11 using System.Threading.Tasks; 12 using System.Windows.Input; 13 14 using ImageResizer.Helpers; 15 using ImageResizer.Models; 16 using ImageResizer.Views; 17 18 namespace ImageResizer.ViewModels 19 { 20 public class ProgressViewModel : Observable, IDisposable 21 { 22 private readonly MainViewModel _mainViewModel; 23 private readonly ResizeBatch _batch; 24 private readonly IMainView _mainView; 25 private readonly Stopwatch _stopwatch = new Stopwatch(); 26 private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); 27 28 private double _progress; 29 private TimeSpan _timeRemaining; 30 private bool disposedValue; 31 32 public ProgressViewModel( 33 ResizeBatch batch, 34 MainViewModel mainViewModel, 35 IMainView mainView) 36 { 37 _batch = batch; 38 _mainViewModel = mainViewModel; 39 _mainView = mainView; 40 41 StartCommand = new RelayCommand(Start); 42 StopCommand = new RelayCommand(Stop); 43 } 44 45 public double Progress 46 { 47 get => _progress; 48 set => Set(ref _progress, value); 49 } 50 51 public TimeSpan TimeRemaining 52 { 53 get => _timeRemaining; 54 set => Set(ref _timeRemaining, value); 55 } 56 57 public ICommand StartCommand { get; } 58 59 public ICommand StopCommand { get; } 60 61 public void Start() 62 { 63 _ = Task.Factory.StartNew(StartExecutingWork, _cancellationTokenSource.Token, TaskCreationOptions.None, TaskScheduler.Current); 64 } 65 66 private void StartExecutingWork() 67 { 68 _stopwatch.Restart(); 69 var errors = _batch.Process( 70 (completed, total) => 71 { 72 var progress = completed / total; 73 Progress = progress; 74 _mainViewModel.Progress = progress; 75 76 TimeRemaining = _stopwatch.Elapsed.Multiply((total - completed) / completed); 77 }, 78 _cancellationTokenSource.Token); 79 80 if (errors.Any()) 81 { 82 _mainViewModel.Progress = 0; 83 _mainViewModel.CurrentPage = new ResultsViewModel(_mainView, errors); 84 } 85 else 86 { 87 _mainView.Close(); 88 } 89 } 90 91 public void Stop() 92 { 93 _cancellationTokenSource.Cancel(); 94 _mainView.Close(); 95 } 96 97 protected virtual void Dispose(bool disposing) 98 { 99 if (!disposedValue) 100 { 101 if (disposing) 102 { 103 _cancellationTokenSource.Dispose(); 104 } 105 106 disposedValue = true; 107 } 108 } 109 110 public void Dispose() 111 { 112 // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method 113 Dispose(disposing: true); 114 GC.SuppressFinalize(this); 115 } 116 } 117 }