OliviaAddInPro/Services/ProcesoEjecServ.cs

551 lines
18 KiB
C#

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<TiposEjecucion> start(string cfg, IprocessManager cps)
{
this.cps = cps;
try
{
soc = new Cstr_socket();
}
catch
{
var resp = new Respuesta<TiposEjecucion>() { 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<TiposEjecucion> 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<TiposEjecucion>() { 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<TiposActu>() { 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<TiposActu> pide_progr()
{
TiposActu tt;
int i;
var res = new Respuesta<TiposActu> { 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<bool> envia_cancel()
{
var res = new Respuesta<bool> { 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<TiposActu> 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.");
//FALTA CAMBIAR EL NOMBRE DEL BOTÓN DE CANCELAR
/*if (actu > TiposActu.ActuFinOk)
cps.SetEstado("Calculando...");
if ((actu == TiposActu.ActuPermu) && !cancela)
cps.SetEstado("Calculando Permutaciones...");
if ((actu == TiposActu.ActuMal) || (actu == TiposActu.ActuFinNOk))
col = 2;
else
col = 1;
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;
}
}
}