using System; using System.IO; using System.Data; using System.Text; using System.Diagnostics; using System.Collections.Generic; using Amib.Threading; using PDFGenerator.BusinessLayer; using PipelineLib; using ContrattoSei.Utilities; using System.Threading; using System.Configuration; using System.Linq; using PDFGenerator.Presentation.TemplateGenerator; namespace GestorePDF.Logic { public class ThreadManager { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); Thread[] pdfGenerationThreads; private void ProcessPdfDocuments(int volThreads) { // Daily FIX20180313: questa nuova pubblicazione generava record multipli su ReportManager e Gestione_PDF_FTP, a causa dell'introduzione della gestione // multithread per la trimestrale in questa parte comune del software. // Abbiamo risolto il problema condizionando il riciclo di riaccodamento solo alla reportistica trimestrale. // Per quella giornaliera, basta un unico accodamento iniziale dei datathread. logger.Debug("ProcessPdfDocuments (int volThreads) {0}", volThreads.ToString()); // Daily FIX20180313 string sPeriodico = ConfigurationManager.AppSettings["Periodico"]; // --Daily FIX20180313 UtilityBusinessLayer ubl = new UtilityBusinessLayer(); logger.Debug("ProcessPdfDocuments richiama getDataThreads(volThreads * 2 = {0}", (volThreads * 2).ToString()); List _dataThreads = ubl.getDataThreads(volThreads * 2); //TemplateGeneratorFactory.LettoreNota = _dataThreads; // ***** Aggiunta Data Thread per Nota dinamica 23022022 Andrea Pino **** // logger.Debug("Creazione di un array di {0} threads", volThreads.ToString()); pdfGenerationThreads = new Thread[volThreads]; logger.Debug("Aggiunta della lista di {0} threads nella coda di thread", _dataThreads.Count.ToString()); AddDataThreadsToQueue(_dataThreads); logger.Debug("Inizio ciclo for da 0 a {0}", (volThreads - 1).ToString()); for (int i = 0; i < volThreads; i++) { logger.Debug("pdfGenerationThreads[{0}] = new Thread(MasterThread.ProcessDataInSingleThread) { IsBackground = true };", i.ToString()); pdfGenerationThreads[i] = new Thread(MasterThread.ProcessDataInSingleThread) { IsBackground = true }; logger.Debug("Sto per lanciare il thread id. {0}",pdfGenerationThreads[i].ManagedThreadId.ToString()); pdfGenerationThreads[i].Start(); } // Daily FIX20180313 if (sPeriodico == "1") { // --Daily FIX20180313 //logger.Debug("Inizio while (_dataThreads != null && _dataThreads.Count > 0)"); while (_dataThreads != null && _dataThreads.Count > 0) { logger.Debug("if (MasterThread.ThreadsQueue.Count < volThreads * 2)"); if (MasterThread.ThreadsQueue.Count < volThreads * 2) { logger.Debug("MasterThread.ThreadsQueue.Count = {0}; volThreads * 2 = {1}", MasterThread.ThreadsQueue.Count.ToString(), (volThreads * 2).ToString()); _dataThreads = ubl.getDataThreads(volThreads); logger.Debug("AddDataThreadsToQueue(_dataThreads)"); AddDataThreadsToQueue(_dataThreads); } Thread.Sleep(500); } } while (true) { int threadsRunning = pdfGenerationThreads.Where(x => x.IsAlive).Count(); if (threadsRunning == 0) { return; } Thread.Sleep(500); } } private void AddDataThreadsToQueue(List dataThreads) { if (dataThreads != null) { foreach (DataThread t in dataThreads) { //logger.Debug("Accodo datathread {0}", t.CodiceFiscale); MasterThread.ThreadsQueue.Enqueue(t); } } } public int Main(int _volThreads = 0) { //logger.Debug("Main (int _volThreads = 0) {0}", _volThreads); Console.WriteLine("Start GestorePdf"); string ambiente = UtilityManager.getAppSetting("ambiente"); string funzione = "GESTORE PDF"; //Invio il flusso giornaliero se il report è periodico e se è abilitato l'invio a host nell'appconfig bool inviaFlussoGiornaliero = (UtilityManager.getAppSetting("Periodico") == "0") && Convert.ToBoolean(UtilityManager.getAppSetting("INVIO_HOST")) ? true : false; int _maxActiveThreads = Convert.ToInt32(UtilityManager.getAppSetting("maxGestoreThreads")); int multiT = int.Parse(UtilityManager.getAppSetting("multiThreadingGestoreThreads")); int volThreads = Int32.Parse(ConfigurationManager.AppSettings["maxGestoreThreads"]); if (_volThreads > 0) volThreads = _volThreads; logger.Debug("volThreads vale {0}", volThreads); string sCulture = UtilityManager.getAppSetting("CultureToUse"); try { System.Globalization.CultureInfo.CreateSpecificCulture(sCulture); //logger.Debug("Main richiama ProcessPdfDocuments(volThreads={0})", volThreads); ProcessPdfDocuments(volThreads); if (inviaFlussoGiornaliero) { funzione = "SmartFTPThread.Program.GestioneFlussoGiornaliero"; #region iFeelGuilty SmartFTPThread.Logic.FtpProcessSeparated.GestioneFlussoGiornaliero(); #endregion inviaFlussoGiornaliero = false; } return 0; } catch (DataBaseException ex) { try { logger.Error(ex.Message); logger.Debug(ex.InnerException); if (inviaFlussoGiornaliero) { funzione = "SmartFTPThread.Program.GestioneFlussoGiornaliero"; #region iFeelGuilty SmartFTPThread.Logic.FtpProcessSeparated.GestioneFlussoGiornaliero(); #endregion iFeelGuilty inviaFlussoGiornaliero = false; } funzione = "ScriviErroreNelDB"; ScriviErroreNelDB(-00002, "Errore nel Gestore PDF: " + getDataBaseException(ex), -292929, "Gestore PDF", "Gestore PDF"); funzione = "GESTORE PDF"; } catch (Exception exc) { funzione += "-ERRORE-" + exc.Message + "-ERRORE-"; try { logger.Error(funzione); } catch { } } try { logger.Error(funzione); } catch { } return -1; } catch (Exception ex) { try { logger.Error(ex.Message); logger.Debug(ex.InnerException); } catch { } try { if (inviaFlussoGiornaliero) { funzione = "SmartFTPThread.Program.GestioneFlussoGiornaliero"; #region iFeelGuilty SmartFTPThread.Logic.FtpProcessSeparated.GestioneFlussoGiornaliero(); #endregion inviaFlussoGiornaliero = false; } funzione = "ScriviErroreNelDB"; ScriviErroreNelDB(-00003, "Errore nel Gestore PDF: " + getException(ex), -292929, "Gestore PDF", "Gestore PDF"); funzione = "GESTORE PDF"; } catch (Exception exc) { funzione += "-ERRORE-" + exc.Message + "-ERRORE-"; try { logger.Error(funzione); } catch { } } try { logger.Error(funzione); } catch { } return -1; } } private static void Start() { } private static string getDataBaseException(DataBaseException ecc) { const string aCapo = "#/n#"; string ritorno = ""; ritorno += aCapo; ritorno += " Informazioni Comando SQL:" + aCapo; ritorno += " sql file name: " + ecc.SqlFileName + aCapo; ritorno += " connection string: " + ecc.ConnectionStringWithoutCredentials + aCapo; //ritorno += " command text: " + ecc.CommandText + aCapo; //controllo se ci sono i parametri if (ecc.Parameters != null) { foreach (Parametro parametro in ecc.Parameters) { ritorno += aCapo; ritorno += " parametro: " + parametro.ParameterName + aCapo; ritorno += " dimensione: " + parametro.Size.ToString() + aCapo; ritorno += " direzione: " + parametro.Direction.ToString() + aCapo; ritorno += " tipo: " + parametro.DbType.ToString() + aCapo; if (parametro.Value == null) ritorno += " valore: null" + aCapo; else { string valoreParametro = ""; if (parametro.Size > 500) { valoreParametro = " valore: null(sono visualizzati solo i primi 500 bytes): " + parametro.Value.ToString().Substring(0, 500); } else { valoreParametro = " valore: " + parametro.Value.ToString(); } ritorno += valoreParametro + aCapo; } } } ritorno += aCapo; ritorno += " tipo: DataBaseException" + aCapo; ritorno += " descrizione: " + ecc.Eccezione.Message + aCapo; ritorno += " sorgente: " + ecc.Eccezione.Source + aCapo; ritorno += " traccia: " + FormattaErrore(ecc.StackTrace) + aCapo; return ritorno; } private static string getException(Exception ecc) { const string aCapo = "#/n#"; string ritorno = ""; ritorno += aCapo; ritorno += " tipo: " + ecc.GetType().ToString() + aCapo; ritorno += " descrizione: " + ecc.Message + aCapo; ritorno += " sorgente: " + ecc.Source + aCapo; if (ecc.InnerException != null) { ritorno += " descrizione Inner: " + ecc.InnerException.Message + aCapo; ritorno += " sorgente Inner: " + ecc.InnerException.Source + aCapo; } ritorno += " traccia: " + FormattaErrore(ecc.StackTrace) + aCapo; return ritorno; } private static string FormattaErrore(string errore) { const string aCapo = "#/n#"; const string spazio = " "; string separatore1 = " at "; string separatore2 = " in "; string separatore3 = ":line "; string erroreInterno = errore.Replace(separatore1, "@"); string ritorno = aCapo; //nome metodo e tutto il resto string[] messaggioErrore = erroreInterno.Split('@'); string messaggioSenzaSpazi; string[] messaggioInterno; foreach (string messaggio in messaggioErrore) { messaggioSenzaSpazi = messaggio.Trim(); if (messaggioSenzaSpazi != "") { messaggioSenzaSpazi = messaggioSenzaSpazi.Replace(separatore2, "@"); messaggioInterno = messaggioSenzaSpazi.Split('@'); if (messaggioInterno.GetUpperBound(0) == 1) { ritorno += spazio + "metodo: " + messaggioInterno[0] + aCapo; string fileLineaSingolo = messaggioInterno[1].Replace(separatore3, "@"); string[] fileLinea = fileLineaSingolo.Split('@'); ritorno += spazio + "percorsoFile: " + fileLinea[0] + aCapo; ritorno += spazio + "linea: " + fileLinea[1] + aCapo; ritorno += aCapo; } else { ritorno += spazio + "metodo: " + messaggioInterno[0] + aCapo; } } } return ritorno; } private static void ScriviErroreNelDB(int codiceErrore, string descrizioErrore, int localeId, string nomePackage, string descrizionePackage) { int scriviErroreNelDB = int.Parse(UtilityManager.getAppSetting("scriviErroreNelDB")); if (scriviErroreNelDB == 1) { List parametri = new List(); Parametro parametro = new Parametro(); parametro.DbType = DbType.Int32; parametro.ParameterName = "codiceErrore"; parametro.Value = codiceErrore; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.String; parametro.ParameterName = "descrizioErrore"; parametro.Value = descrizioErrore; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.DateTime; parametro.ParameterName = "dataTime"; parametro.Value = DateTime.Now; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.String; parametro.ParameterName = "localeID"; if (localeId == 0) parametro.Value = System.DBNull.Value; else parametro.Value = localeId; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.String; parametro.ParameterName = "descrizionePackage"; parametro.Value = descrizionePackage; parametri.Add(parametro); parametro = new Parametro(); parametro.DbType = DbType.String; parametro.ParameterName = "nomePackage"; parametro.Value = nomePackage; parametri.Add(parametro); DataAccess.ExecuteNonQueryStoredProcedure(DBProvider.SqlServerStampeC6, "[C6Mart].[UT_INSERT_ERROR]", parametri); } } } }