using System; using System.Threading.Tasks; using DataLayer; using Dinah.Core.ErrorHandling; using Dinah.Core.Net.Http; namespace FileLiberator { public abstract class DownloadableBase : IDownloadable { public event EventHandler Begin; public event EventHandler Completed; public event EventHandler DownloadBegin; public event EventHandler DownloadProgressChanged; public event EventHandler DownloadCompleted; public event EventHandler StatusUpdate; protected void Invoke_StatusUpdate(string message) => StatusUpdate?.Invoke(this, message); public abstract bool Validate(LibraryBook libraryBook); public abstract Task ProcessItemAsync(LibraryBook libraryBook); // do NOT use ConfigureAwait(false) on ProcessAsync() // often calls events which prints to forms in the UI context public async Task ProcessAsync(LibraryBook libraryBook) { Begin?.Invoke(this, libraryBook); try { return await ProcessItemAsync(libraryBook); } finally { Completed?.Invoke(this, libraryBook); } } protected async Task PerformDownloadAsync(string proposedDownloadFilePath, Func, Task> func) { var progress = new Progress(); progress.ProgressChanged += (_, e) => DownloadProgressChanged?.Invoke(this, e); DownloadBegin?.Invoke(this, proposedDownloadFilePath); try { var result = await func(progress); StatusUpdate?.Invoke(this, result); return result; } finally { DownloadCompleted?.Invoke(this, proposedDownloadFilePath); } } } }