/// <summary> /// Creates the company export file. /// </summary> /// <param name="companyId">The company identifier.</param> /// <param name="userId">The user identifier.</param> /// <param name="fileSize">Size of the file.</param> /// <returns>Is success.</returns> private bool CreateCompanyExportFile(int companyId, int userId, out long fileSize) { CompanyBL companyBL = new CompanyBL(DataContext); string baseFolder = companyBL.GetExportFileLocation(Common.Constants.GlobalConstants.RelatedTables.ExportFiles.Company, companyId); if (baseFolder.Trim().Length > 0) { try { // Intialize Cancellation Token. CancellationTokenSource cts = new CancellationTokenSource(); ParallelOptions po = new ParallelOptions(); po.CancellationToken = cts.Token; string bookingPath = Path.Combine(baseFolder, "Bookings"); FileHandler.CreateFolder(bookingPath); // Generate booking reports.(new Task/Thread.) Task bookingReportTask = Task.Factory.StartNew(() => { try { GenerateCompanyInventoryBookingReports(companyId, userId, bookingPath); } catch (Exception ex) { // Request cancel for all other pending tasks. And throw the exception. cts.Cancel(); throw ex; } }, cts.Token); // Generate item type reports and item brief attachements.(new Task/Thread.) Task itemTypeTask = Task.Factory.StartNew(() => { var groupedDocumentMedias = companyBL.GetItemTypeDocumentMediaByCompany(companyId); // Check for the cancel request. (after starting the task). cts.Token.ThrowIfCancellationRequested(); Parallel.ForEach <ItemTypeDocumentMedia>(groupedDocumentMedias, po, dm => { try { // Create Item List with all Specs report Task itemReportTask = Task.Factory.StartNew(() => { try { string fileName = string.Concat(dm.ItemTypeName, " - Item List with all Specs"); string fileNameExtension = GlobalConstants.FileExtensions.ExcelFile; string encoding; string mimeType; string attachmentPathCI = Path.Combine(baseFolder, dm.ItemTypeName); byte[] reportBytes = UserWebReportHandler.GenerateInventoryExport(companyId, dm.ItemTypeId, ReportTypes.Excel, out fileNameExtension, out encoding, out mimeType); FileHandler.SaveFileToDisk(reportBytes, string.Format("{0}.{1}", fileName, fileNameExtension), attachmentPathCI).Wait(); } catch (Exception ex) { // Request cancel for all other pending tasks. And throw the exception. cts.Cancel(); //throw ex; } }, cts.Token); string attachmentPath = Path.Combine(baseFolder, dm.ItemTypeName, "Attachments"); FileHandler.CreateFolder(attachmentPath); // Generate attachments. // single threaded. // Due to the fact that this is an heavy IO bound operation which is recomended to do async. List <Task> asyncTaskList = new List <Task>(); foreach (DocumentMediaInfo documentMediaInfo in dm.DocumentMedias) { // Check for the cancel request. (after starting the task). cts.Token.ThrowIfCancellationRequested(); string filePrefix = string.Format("{0} {1} - ", documentMediaInfo.EntityId, Utils.Ellipsize(documentMediaInfo.EntityName, 50)); asyncTaskList.Add(SaveDocumentMedia(filePrefix, documentMediaInfo.DocumentMediaId, attachmentPath)); } // Wait for all async taks. Task.WaitAll(asyncTaskList.ToArray()); // Wait for report task. itemReportTask.Wait(); } catch (Exception ex) { // Request cancel for all other pending tasks. And throw the exception. cts.Cancel(); throw ex; } }); }, cts.Token); Task[] tasks = new[] { bookingReportTask, itemTypeTask }; try { Task.WaitAll(tasks, cts.Token); string zipPath = string.Concat(baseFolder, ".zip"); FileHandler.CreateZipFile(baseFolder, zipPath); fileSize = FileHandler.GetFileSize(zipPath); return(true); } catch (OperationCanceledException) { // One or more operations has been canceled. Wait for other running tasks to complete. (Any status => success or failed). Task.Factory.ContinueWhenAll(tasks, _ => { // Get exceptions from failed tasks. Exception[] exceptions = tasks.Where(t => t.IsFaulted).Select(t => t.Exception).ToArray(); foreach (Exception e in exceptions) { // log failures. AgentErrorLog.HandleException(e); } }).Wait(); } } catch (AggregateException ae) { foreach (Exception e in ae.Flatten().InnerExceptions) { // log failures. AgentErrorLog.HandleException(e); } } finally { FileHandler.DeleteFolder(baseFolder); } } fileSize = 0; return(false); }