//nunca se puede acceder a elementos de la interfaz directamente desde este metodo, acceder a la interfaz desde otro thread
        //bloquea la aplicacion
        private void BackGround_Work(object sender, DoWorkEventArgs e)
        {
#if DEBUG
            int porc       = 0;
            var totalTimer = new Stopwatch();
            totalTimer.Start();
            var timer = new Stopwatch();
            timer.Start();
#endif
            bgwBlnOffArgument args    = (bgwBlnOffArgument)e.Argument;
            bgwBlnOffResult   results = new bgwBlnOffResult();

            if (args.BLnOffEnabled)
            {
                //Se crean objetos que contienen las tablas de datos que se necesitan en esta herramienta
                Colindancias colindancias = new Colindancias();
                RSLTE31      R31          = new RSLTE31(args.lnBtsInputs, args.pathR31);
                R31.completeR31(args.pathSRAN, args.pathFL18, args.pathSRAN2, args.srandividio, args.conFL18);

#if DEBUG
                timer.Stop();
                Console.WriteLine("Completar consulta31: " + timer.Elapsed.ToString(@"m\:ss\.fff"));
                timer.Reset();
                timer.Start();
#endif

                TimingAdvance TA = new TimingAdvance(args.lnBtsInputs, args.pathTA);

#if DEBUG
                timer.Stop();
                Console.WriteLine("Sacar Timing Advance: " + timer.Elapsed.ToString(@"m\:ss\.fff"));
                timer.Reset();
                timer.Start();
#endif
                Exports export = new Exports(TA.GetColumn("LNCEL name"), args.pathSRAN, args.pathFL18, args.pathSRAN2, args.srandividio, args.conFL18);
#if DEBUG
                timer.Stop();
                Console.WriteLine("Sacar Exports: " + timer.Elapsed.ToString(@"m\:ss\.fff"));
                timer.Reset();
                timer.Start();
                porc = 5;
                worker.ReportProgress(porc);
#endif

                foreach (DataRow dataRow in export.data.Rows)
                {
                    colindancias.CheckColin(dataRow, R31);
                }
                int a = 0;

                foreach (DataRow dataRow in R31.NotInExports())
                {
                    colindancias.CheckColinsNotInExports(dataRow);
                }
                colindancias.AddENBID();

                if (args.rellenarLabel)
                {
                    colindancias.rellenarLabelUnknown(args.pathSRAN, args.pathSRAN2, args.srandividio);
                }



                porc = 15;
                worker.ReportProgress(porc);

                //Dibujar tablas
                DataView dv = colindancias.data.DefaultView;
                dv.Sort                 = "[HO errores SR] DESC";
                colindancias.data       = dv.ToTable();
                results.colindancias    = colindancias.data;
                results.siteCoordErrors = colindancias.GetSiteCoordErr();

                porc = 25;


#if DEBUG
                timer.Stop();
                Console.WriteLine("Calcular Colindancias: " + timer.Elapsed.ToString(@"m\:ss\.fff"));
                timer.Reset();
                timer.Start();
#endif

                //Se calculan las candidatas para BlackListing y para Offset, que quedaran disponibles para la edicion manual del usuario en la interfaz grafica
                CandidatesBL candBL = new CandidatesBL(colindancias);
                dv             = candBL.data.DefaultView;
                dv.Sort        = "[HO errores SR] DESC";
                candBL.data    = dv.ToTable();
                results.candBl = candBL.data;
                porc           = 50;
#if DEBUG
                timer.Stop();
                Console.WriteLine("Calcular candidatas de blacklisting: " + timer.Elapsed.ToString(@"m\:ss\.fff"));
                timer.Reset();
                timer.Start();
#endif

                CandidatesOFF candOFF = new CandidatesOFF(TA, colindancias, candBL);
                dv              = candOFF.data.DefaultView;
                dv.Sort         = "[HO errores SR] DESC";
                candOFF.data    = dv.ToTable();
                results.candOff = candOFF.data;

                porc = 75;
                worker.ReportProgress(porc);

#if DEBUG
                timer.Stop();
                Console.WriteLine("Calcular candidatas de offset: " + timer.Elapsed.ToString(@"m\:ss\.fff"));
                timer.Reset();
                timer.Start();
#endif
            }
            if (args.prevAnalisysEnabled)
            {
                NIR48H nir = new NIR48H(args.lnBtsInputs, args.pathNIR48);
                results.error       = nir.errors;
                results.nirPlotData = nir.data;
#if DEBUG
                timer.Stop();
                Console.WriteLine("Analisis Previo: " + timer.Elapsed.ToString(@"m\:ss\.fff"));
#endif
            }
            e.Result = results;

            porc = 100;
            worker.ReportProgress(porc);
#if DEBUG
            timer.Stop();
            totalTimer.Stop();
            Console.WriteLine("Tiempo Total: " + totalTimer.Elapsed.ToString(@"m\:ss\.fff"));
#endif
        }
        //tras acabar el procesado en segundo plano se actualiza la interfaz con ellos
        private void BackGround_Completed(object sender, RunWorkerCompletedEventArgs e)
        {
            // Progress_Bar.Value = 100;
            if (e.Error == null)
            {
                //Paramos de girar el cursor
                Cursor = Cursors.Arrow;

                plotNodo.Visibility   = Visibility;
                plotceldas.Visibility = Visibility;


                bgwBlnOffResult output = (bgwBlnOffResult)e.Result;
                Copiaoutput = output;
                if (output.colindancias != null)
                {
                    colinGrid.WorkingData = output.colindancias;
                    WPFForms.FindParent <TabItem>(colinGrid).Visibility = Visibility.Visible;
                    tabColindancias.IsSelected = true;



                    //fc = new formColindancias(output.colindancias);

                    //fc.Show();
                }

                if (output.siteCoordErrors != "" && (bool)Is_BlnOFF_Enabled.IsChecked)
                {
                    WPFForms.ShowError("Faltan las coordenadas de los siguientes emplazamientos", output.siteCoordErrors);
                }

                if (output.candBl != null)
                {
                    candBLGrid.WorkingData = output.candBl;
                    WPFForms.FindParent <TabItem>(candBLGrid).Visibility = Visibility.Visible;
                }
                if (output.candOff != null)
                {
                    candOFFGrid.WorkingData = output.candOff;
                    WPFForms.FindParent <TabItem>(candOFFGrid).Visibility = Visibility.Visible;
                }
                if (output.error != null)
                {   //se genera la tabla de analis previo
                    errGrid.WorkingData = output.error;
                    WPFForms.FindParent <TabItem>(errGrid).Visibility = Visibility.Visible;

                    //se genera la gárafica por nodos
                    this.erroresAMejorar = output.error;

                    List <string> sites = erroresAMejorar.AsEnumerable().Select(col => (string)col[1]).Distinct().ToList();
                    siteListBox_1.ItemsSource  = sites;
                    siteListBox_1.SelectedItem = sites[0];

                    List <string> Tech = this.erroresAMejorar.AsEnumerable().Where(row => (string)row[1] == (string)siteListBox_1.SelectedItem).Select(col => (string)col[2]).Distinct().ToList <string>();
                    techListBox_1.ItemsSource  = Tech;
                    techListBox_1.SelectedItem = Tech[0];

                    UpdateGraph_1();
                }
                if (output.nirPlotData != null)
                {
                    this.nirPlotData = output.nirPlotData;

                    List <string> sites = erroresAMejorar.AsEnumerable().Select(col => (string)col[1]).Distinct().ToList();
                    siteListBox_2.ItemsSource  = sites;
                    siteListBox_2.SelectedItem = sites[0];

                    List <string> tech = this.nirPlotData.AsEnumerable().Where(row => (string)row[1] == (string)siteListBox_2.SelectedItem).Select(col => (string)col[3]).Distinct().ToList <string>();
                    techListBox_2.ItemsSource  = tech;
                    techListBox_2.SelectedItem = tech[0];

                    var cells2Plot = nirPlotData.AsEnumerable()
                                     .Where(row => (string)row[1] == (string)siteListBox_2.SelectedItem && (string)row[3] == (string)techListBox_2.SelectedItem)
                                     .Select(col => (string)col[2]).Distinct().Where(item => !item.Contains("="));

                    List <SectorListItem> sectors = new List <SectorListItem>();
                    foreach (var cell in cells2Plot)
                    {
                        sectors.Add(new SectorListItem()
                        {
                            Enabled = true, Sector = TECH_NUM.GetSectorFromLNCEL(cell)
                        });
                    }
                    this.Sectors = sectors;

                    Binding codeBinding = new Binding("Sectors");
                    codeBinding.Source = this;
                    sectorListBox.SetBinding(ListBox.ItemsSourceProperty, codeBinding);

                    UpdateGraph_2();
                }
            }
            else
            {
                //Paramos de girar el cursor
                Cursor = Cursors.Arrow;

                //control de errores en BackGround
                switch (e.Error.GetType().Name)
                {
                case "FileNotFoundException":
                    WPFForms.ShowError("Falta un archivo", e.Error.Message);
                    break;

                case "InvalidOperationException":
                    WPFForms.ShowError("Error critico", e.Error.Message);
                    break;

                case "ArgumentException":
                    WPFForms.ShowError("Error en los datos", e.Error.Message);
                    break;

                default:
                    WPFForms.ShowError("No controlado", e.Error.Message);
                    break;
                }
            }
        }