Esempio n. 1
0
        /// <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);
        }