public static async Task <Book> GetBook(string id, string uri, string folder, CancellationToken cancellationToken, Action <string> onProcess, Action <Book> onParsed, Action <Book> onCompleted, Action <Book, Exception> onError, Action <string, List <string> > onChapterCompleted, Action <string, Exception> onChapterError, Action <string, string> onDownloadFileCompleted, Action <string, Exception> onDownloadFileError, int crawlMethod) { cancellationToken.ThrowIfCancellationRequested(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // parse book Book book = null; try { book = await ISach.ParseBook(uri, cancellationToken); book.PermanentID = string.IsNullOrWhiteSpace(id) ? Utility.GetUUID() : id; if (string.IsNullOrWhiteSpace(book.Title) && onError != null) { onError(book, new InformationInvalidException("The book is invalid")); return(null); } else if (onParsed != null) { onParsed(book); } } catch (Exception ex) { if (onError != null) { onError(book, ex); return(null); } else { throw ex; } } // fetch chapters book = await ISach.FetchChapters(book, folder, cancellationToken, onProcess, onChapterCompleted, onChapterError, onDownloadFileCompleted, onDownloadFileError, crawlMethod); stopwatch.Stop(); if (onProcess != null) { onProcess("..... Total times for processing: " + stopwatch.GetElapsedTimes()); } // callback when done if (onCompleted != null) { onCompleted(book); } return(book); }