using ArcGIS.Desktop.Framework.Threading.Tasks; using OliviaAddIn; using OliviaAddInPro.Model; using OliviaAddInPro.Model.contract; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace OliviaAddInPro.Services { public class ProcesoEjecServ { Cstr_socket soc = null; int m_out=0; int m_miliseconds=200; int m_tm_progr=1000; int modo_fin = 0; bool cancela = false; bool cancela_fin = false; bool conectado = false; bool permu = false; bool cancela_permu = false; int progr = 0; string args = ""; string str_cfg = ""; string tarea = ""; public string err_str = ""; double x, y; IprocessManager cps; enum TiposActu { ActuMal, ActuNoActu, ActuBien, ActuPermu, ActuMulti, ActuFinOk, ActuSect, ActuPlan, ActuFinNOk, ActuN, } public string Ip { get; set; } public int Puerto { get; set; } public ProcesoEjecServ() { } public Respuesta start(string cfg, IprocessManager cps) { this.cps = cps; try { soc = new Cstr_socket(); } catch { var resp = new Respuesta() { Value = TiposEjecucion.FinEjecNOk }; resp.Error.Add("Error al crear conexión con olivia task (no se pudo crear socket)"); return resp; } str_cfg = cfg; /* await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => { run(); };*/ var res = run(); try { soc.termina(); } catch { res.Error.Add("Error al cerrar la conexion con olivia task (no se pudo cerrar el socket)"); } return res; } private Respuesta run() { int nint = 0; int nint_max = 5; bool sal = false; bool first_send_cfg = true; bool fin = false; int lastprog = 0; var res = new Respuesta() { Value = TiposEjecucion.FinEjecNOk }; cps.SetProceso("Procesando Datos"); cps.SetProgress(0); try { do { Thread.Sleep(m_miliseconds); if (first_send_cfg)//a continuación envía la configuración { Thread.Sleep(500); if (!envia_cfg()) { if (nint >= nint_max) { res.Error.Add("Error en la comunicación con OliviaTask"); var act = new Respuesta() { Value = TiposActu.ActuFinNOk }; act.Error.AddRange(res.Error); actualiza(act); sal = true; } else nint++; } else { first_send_cfg = false; nint = 0; } } if (cps.Getcancelled()) //mira a ver si ha cancelado el usuario { //se ha cancelado, lo envía al OliviaTask envia_cancel(); if (!cancela_permu) sal = true; else { cancela_permu = false; } if(!fin) //si no ha finalizado normal, el usuario lo ha cancelado res.Error.Add("Proceso Cancelado por el usuario"); } else if (!first_send_cfg && ((Math.Abs(Environment.TickCount) - lastprog) >= m_tm_progr) && !fin) //en caso normal, todo va bien, pide el progreso y la tarea { //solo pide la programación cada m_tm_progr milis var pp = pide_progr(); if (pp .Value> TiposActu.ActuFinOk) fin = true; if(pp.HasError) { if (nint >= nint_max) { res.Error.Add(pp.Error.FirstOrDefault()); sal = true; } else nint++; } actualiza(pp); lastprog = Environment.TickCount; } } while (!sal); } catch (Exception e) { res.Error.Add(e.Message); //MessageBox.Show("Error durante el proceso.", "Olivia", MessageBoxButtons.OK, MessageBoxIcon.Error); return res; } if (!res.HasError) res.Value = TiposEjecucion.FinEjecOk; return res; } //funciones auxiliares---------------------------------------- private bool conecta() { if (!conectado) { if (!soc.conecta(Ip, Puerto)) { conectado = false; return false; } conectado = true; } return true; } /** * Envía la información de la configuración por socket a OliviaTask */ public bool envia_cfg() { string args; try { if (!conecta()) return false; if (str_cfg == null || str_cfg.Length == 0) return false; if (!soc.envia(str_cfg)) { conectado = false; return false; } args = soc.recibe(); if ((args.Length == 0) || (args != GeneralDef.SockConfOk)) return false; return true; } catch (Exception) { return false; } } /** * Pide por socket la información de sectorización a OliviaTask */ private bool pide_sect() { //pide sectorización porque ya ha sido avisado de que ha terminado try { if (!conecta()) return false; //pide secto if (!soc.envia(GeneralDef.SockSect)) { conectado = false; return false; } //recibe sectorización args = soc.recibe(); if (args.Length == 0) return false; return true; } catch (Exception) { return false; } } /** * Pide por socket la información de progreso a OliviaTask * Devuelve 0 si ha ido mal, 1 si ha ido bien, 2 si ha recibido que hay que pedir sectorización */ private Respuesta pide_progr() { TiposActu tt; int i; var res = new Respuesta { Value = TiposActu.ActuMal }; //pide progreso y tarea por la que va try { if (!conecta()) { res.Error.Add("Error en la comunicación con OliviaTask"); return res; } //pide progreso if (!soc.envia(GeneralDef.SockProgr)) { conectado = false; res.Error.Add("Error en la comunicación con OliviaTask"); return res; } //recibe progreso args = soc.recibe(); if (args.Length == 0) { res.Value = TiposActu.ActuNoActu; return res; } //comprueba progreso try { progr = Convert.ToInt32(args); if (progr < 0 || progr > GeneralDef.ProgrMax) { res.Value = TiposActu.ActuNoActu; return res; } } catch { res.Value = TiposActu.ActuNoActu; return res; } //pide tarea if (!soc.envia(GeneralDef.SockTarea)) { res.Error.Add( ""); return res; } //recibe tarea args = soc.recibe(); if (args.Length == 0) { res.Error.Add("Error recibe tarea mal"); return res; } if (args == "0") //se ha mezclado el progreso, vuelve a recibir la tarea args = soc.recibe(); if (args.Length == 0) { res.Error.Add("Error recibe tarea mal"); return res; } i = 0; tt = TiposActu.ActuBien; //comprueba tarea if (args.StartsWith(GeneralDef.SockSectFin)) { i = GeneralDef.SockSectFin.Length; tt = TiposActu.ActuSect; } else if (args.StartsWith(GeneralDef.SockPlanFin)) { i = GeneralDef.SockPlanFin.Length; tt = TiposActu.ActuPlan; } else if (args.StartsWith(GeneralDef.SockFinOk)) { i = GeneralDef.SockFinOk.Length; tt = TiposActu.ActuFinOk; } else if (args.StartsWith(GeneralDef.SockFinNOk)) { i = GeneralDef.SockFinNOk.Length; tt = TiposActu.ActuFinNOk; } else if (args.Contains("permutaciones")) { tt = TiposActu.ActuPermu; } else if (args.Contains("multitask")) { tt = TiposActu.ActuMulti; } modo_fin = (int)tt; tarea = args.Substring(i); res.Value = tt; return res; } catch (Exception) { res.Error.Add("Error al preguntar por el progreso."); return res; } } /** * Envía a OliviaTask la orden de cancelar el proceso */ private Respuesta envia_cancel() { var res = new Respuesta { Value = false }; try { if (!conectado) return res; //envía cancel if (!soc.envia(GeneralDef.SockCanc)) return res; //recibe respuesta args = soc.recibe(); if (args.Length == 0) return res; //comprueba que ok if (args != GeneralDef.SockCancOk) return res; res.Value = true; return res; } catch (Exception) { res.Error.Add("Error al cancelar el progreso."); res.Value = false; //MessageBox.Show("Error al cancelar el progreso.", "Olivia", MessageBoxButtons.OK, MessageBoxIcon.Error); return res; } } /** * Actualiza la barra de progreso * bool fallo_soc : indica si ha habido fallo en el socket */ private void actualiza(Respuesta actu) { try { permu = false; //actualiza la barra de tarea y el texto switch (actu.Value) { case TiposActu.ActuBien: { pon_progr(progr); pon_texto(tarea); break; } case TiposActu.ActuMal: { if (actu.HasError) pon_texto(actu.Error.FirstOrDefault()); else pon_texto(tarea); break; } case TiposActu.ActuFinOk: { pon_progr(100); pon_texto("Finalizado proceso con éxito"); pon_textBtn("Finalizar"); break; } case TiposActu.ActuFinNOk: { pon_progr(100); err_str = "Finalizado proceso con fallos\n" + tarea; pon_texto(err_str); pon_textBtn("Finalizar"); break; } case TiposActu.ActuSect: { pon_progr(100); pon_texto("Finalizada sectorización\n" + tarea); pon_textBtn("Finalizar"); break; } case TiposActu.ActuPlan: { pon_progr(100); pon_texto("Finalizada planificación\n" + tarea); pon_textBtn("Finalizar"); break; } case TiposActu.ActuPermu: { permu = true; pon_texto(tarea); //pon_estilo(ProgressBarStyle.Marquee); break; } case TiposActu.ActuMulti: { pon_texto(tarea); //pon_estilo(ProgressBarStyle.Marquee); break; } default: return; } /* if (actu != TiposActu.ActuPermu && actu != TiposActu.ActuMulti) pon_estilo(ProgressBarStyle.Continuous);*/ pon_barstate(actu.Value); } catch (Exception) { //MessageBox.Show("Error al actualizar el progreso.", "Olivia", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /* * Para poder actualizar el texto de la ventana de progreso hay que llamar a invoke * porque está desde otro thread */ private void pon_texto(String txt) { cps.SetEstado(txt); } private void pon_textBtn(String txt) { cps.SetTextBtn(txt); } /* * Para poder actualizar la barra de progreso hay que llamar a invoke * porque está desde otro thread * Actualiza el tipo de progreso y el texto */ private void pon_estilo() { //cps.Status } /* * Para poder actualizar la barra de progreso hay que llamar a invoke * porque está desde otro thread * Actualiza el estilo para indicar que ha habido error */ private void pon_barstate(TiposActu actu) { int col = 1; if ((actu == TiposActu.ActuMal) || (actu == TiposActu.ActuFinNOk)) cps.SetProceso("Proceso Finalizado con errores."); else if(actu == TiposActu.ActuFinOk) cps.SetProceso("Proceso Finalizado."); if ((actu == TiposActu.ActuMal) || (actu == TiposActu.ActuFinNOk)) cps.PonBarColorRojo(); else cps.PonBarColorVerde(); /*if (actu > TiposActu.ActuFinOk) cps.SetEstado("Calculando..."); if ((actu == TiposActu.ActuPermu) && !cancela) cps.SetEstado("Calculando Permutaciones..."); if (actu > TiposActu.ActuFinOk) button_canc.Text = "Finalizar"; if ((actu == TiposActu.ActuPermu) && !cancela) button_canc.Text = "Parar permu.";*/ } /* * Para poder actualizar la barra de progreso hay que llamar a invoke * porque está desde otro thread * Actualiza el progreso */ private void pon_progr(int pro) { cps.SetProgress( pro); } //configura los parámetros de la conexión public void ConfigConex() { var conf = ConfigServ.Serv.Leer(); Puerto = conf.Puerto; Ip = conf.Ip; } } }