Является ли асинхронный контроллер жизнеспособным вариантом? - PullRequest
0 голосов
/ 29 июня 2011

В настоящее время у меня есть этот огромный и медленный код, который выполняется вечно… Я нахожусь в процессе его рефакторинга, чтобы сделать его несколько более читабельным и в целом обеспечить более быструю работу… По сути, у меня на сервере есть папка, в которой хранятся текстовые файлы с большим количеством данных ... этот сценарий будет считывать из этих файлов и через EF добавлять элементы в базу данных ... загрузка занимает много времени.

    public class ScriptMetabolicoController : Controller
        {
            private IPortalAdministradorServices _servicioPortalAdministrador = new PortalAdministradorServices();            
IRepositorio<Historia> historiarepo = new Repositorio<Historia>();
                IRepositorio<Indicador_Metabolico> indicadorrepo = new Repositorio<Indicador_Metabolico>();

            [Authorize(Roles = "Administrador")]
            public ActionResult Index()
            {


                DirectoryInfo myDir = new DirectoryInfo(Server.MapPath("labtelFTP"));


                ViewData["sinActualizacionesPendientes"] = false;
                if (myDir.GetFiles().Count() != 0)
                {
                    try
                    {
                        foreach (FileInfo file in myDir.GetFiles())
                        {
                            if (file.Extension != ".aspx")
                            {
                                StreamReader stream;
                                stream = file.OpenText();

                                while (stream.Peek() != -1)
                                {
                                    string linea = stream.ReadLine();
                                    string cedula = linea.Substring(2, 18).Trim();
                                    Historia historia;
                                    if (historiarepo.ObtenerTodos().Where(h => h.Cedula == cedula).Count() == 1)
                                    {
                                        //Se obtiene la historia por la cédula del participante
                                        historia = historiarepo.ObtenerTodos().Where(h => h.Cedula == cedula).First();

                                        //Se inicializan las fechas de solicitud y las fechas de reporte del examen que se lee del archivo
                                        var numero = historia.Examenes_Metabolicos.Count();

                                        int anor = Convert.ToInt32(linea.Substring(216, 4));
                                        int mesr = Convert.ToInt32(linea.Substring(220, 2));
                                        int diar = Convert.ToInt32(linea.Substring(222, 2));
                                        DateTime fecha_reporte = new DateTime(anor, mesr, diar);

                                        int anos = Convert.ToInt32(linea.Substring(202, 4));
                                        int mess = Convert.ToInt32(linea.Substring(206, 2));
                                        int dias = Convert.ToInt32(linea.Substring(208, 2));
                                        DateTime fecha_solicitud = new DateTime(anos, mess, dias);

                                        //Variable que tendrá el examen en cuestión
                                        Examen_Metabolico examen;

                                        //Si es el primer indicador de un examen nuevo en la historia del participante se crea una instancia nueva
                                        if (historia.Examenes_Metabolicos.Where(e => e.Fecha_Solicitud == fecha_solicitud).Count() == 0)
                                        {

                                            examen = new Examen_Metabolico();
                                            examen.Fecha_Reporte = fecha_reporte;
                                            examen.Fecha_Solicitud = fecha_solicitud;
                                            historia.Examenes_Metabolicos.Add(examen);

                                            //Se crea en base de datos el examen vacío para luego agregarle valores metabólicos asociados a el.
                                            //historiarepo.GuardarTodo();
                                        }
                                        //Si el indicador no es el primero de un examen nuevo entonces se le asigna a la variable 'examen' la referencia del mismo
                                        else
                                        {
                                            examen = historia.Examenes_Metabolicos.Where(e => e.Fecha_Solicitud == fecha_solicitud).First();
                                        }

                                        //Se lee el código del indicador metabólico
                                        string codigo = linea.Substring(236, 6).Trim();

                                        //Si en efecto el indicador presente en la línea que se está leyendo existe se prosigue a anexarlos al examen
                                        if (indicadorrepo.ObtenerTodos().Where(i => i.Codigo == codigo).Count() != 0)
                                        {
                                            //Se carga el indicador con el que se está trabajando en una línea específica
                                            Indicador_Metabolico indicador = indicadorrepo.ObtenerTodos().Where(i => i.Codigo == codigo).First();

                                            //Se crea una nueva instancia de valor metabólico
                                            Valor_Metabolico val = new Valor_Metabolico();

                                            //Se obtienen los valores del indicador de la línea del archivo que se está leyendo
                                            string rango_alto = linea.Substring(194, 6).Trim();
                                            string rango_bajo = linea.Substring(188, 6).Trim();
                                            string unidades = linea.Substring(178, 10).Trim();
                                            bool alerta = false;
                                            string al = linea.Substring(200, 2).Trim();
                                            if (al != "")
                                                alerta = true;
                                            string valor = linea.Substring(118, 60).Trim();

                                            //Se inicializan los atributos del valor metabólico                                        
                                            //val.Examen_Metabolico_Id = examen.Id;
                                            //val.Indicador_Metabolico_Id = indicador.Id;
                                            val.Unidades = unidades;
                                            val.Rango_Alto = rango_alto;
                                            val.Rango_Bajo = rango_bajo;
                                            val.Valor = valor;
                                            val.Alerta = alerta;
                                            val.Indicador_Metabolico = indicador;
                                            examen.Valores_Metabolicos.Add(val);
                                            historiarepo.GuardarTodo();
                                        }
                                    }
                                }
                                stream.Close();
                                file.MoveTo(Path.Combine(Server.MapPath("BackuplabtelFTP"), file.Name));
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        ViewData["Error"] = true;
                        return View();
                    }
                    ViewData["Error"] = false;
                    return View();
                }
                else
                {
                    ViewData["sinActualizacionesPendientes"] = true;
                    return View();
                }
            }

        }

Я знаю, что есть функция, называемая асинхронными контроллерами, но я не уверен, предназначены ли они для этого случая ...

Пожалуйста, дайте мне несколько советов, как сделать это лучше.

пс. Я также хотел бы, чтобы этот скрипт вызывался регулярно (раз в час), но я тоже не уверен, как это сделать ..

Ответы [ 2 ]

0 голосов
/ 29 июня 2011

Проверить это может помочь http://quartznet.sourceforge.net/. Я планирую использовать его в своем текущем проекте для планирования некоторых более длительных задач.

0 голосов
/ 29 июня 2011

Нужно ли это делать в MVC? Похоже, что это может быть сделано с помощью чего-то вроде службы Windows (что может быть немного болезненно) или какого-либо другого запланированного приложения, возможно даже консольного приложения. Для повторяющихся задач, которые просто работают с файловыми системами или с БД, я использую консольное приложение, которое использует System.Threading.Timers. Вы позволяете фоновым потокам таймера работать, и ваше веб-приложение может свободно делать, ну, в общем, веб-вещи:)

Если это необходимо для работы в Интернете, вот полезный пост о том, как выполнять простые повторяющиеся задачи.

http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

Если вы хотите превратить ваше действие в асинхронное действие, то ваш контроллер будет выглядеть примерно так:

public class ScriptMetabolicoController : AsyncController
    {
        private IPortalAdministradorServices _servicioPortalAdministrador = new PortalAdministradorServices();

           IRepositorio<Historia> historiarepo = new Repositorio<Historia>();
        IRepositorio<Indicador_Metabolico> indicadorrepo = new Repositorio<Indicador_Metabolico>();

        [Authorize(Roles = "Administrador")]
        public void IndexAsync()
        {
            AsyncManager.OutstandingOperations.Increment();

            DirectoryInfo myDir = new DirectoryInfo(Server.MapPath("labtelFTP"));

            AsyncManager.Parameters["sinActualizacionesPendientes"] = false;
            if (myDir.GetFiles().Count() != 0)
            {
                try
                {
                    foreach (FileInfo file in myDir.GetFiles())
                    {
                        if (file.Extension != ".aspx")
                        {
                            StreamReader stream;
                            stream = file.OpenText();

                            while (stream.Peek() != -1)
                            {
                                string linea = stream.ReadLine();
                                string cedula = linea.Substring(2, 18).Trim();
                                Historia historia;
                                if (historiarepo.ObtenerTodos().Where(h => h.Cedula == cedula).Count() == 1)
                                {
                                    //Se obtiene la historia por la cédula del participante
                                    historia = historiarepo.ObtenerTodos().Where(h => h.Cedula == cedula).First();

                                    //Se inicializan las fechas de solicitud y las fechas de reporte del examen que se lee del archivo
                                    var numero = historia.Examenes_Metabolicos.Count();

                                    int anor = Convert.ToInt32(linea.Substring(216, 4));
                                    int mesr = Convert.ToInt32(linea.Substring(220, 2));
                                    int diar = Convert.ToInt32(linea.Substring(222, 2));
                                    DateTime fecha_reporte = new DateTime(anor, mesr, diar);

                                    int anos = Convert.ToInt32(linea.Substring(202, 4));
                                    int mess = Convert.ToInt32(linea.Substring(206, 2));
                                    int dias = Convert.ToInt32(linea.Substring(208, 2));
                                    DateTime fecha_solicitud = new DateTime(anos, mess, dias);

                                    //Variable que tendrá el examen en cuestión
                                    Examen_Metabolico examen;

                                    //Si es el primer indicador de un examen nuevo en la historia del participante se crea una instancia nueva
                                    if (historia.Examenes_Metabolicos.Where(e => e.Fecha_Solicitud == fecha_solicitud).Count() == 0)
                                    {

                                        examen = new Examen_Metabolico();
                                        examen.Fecha_Reporte = fecha_reporte;
                                        examen.Fecha_Solicitud = fecha_solicitud;
                                        historia.Examenes_Metabolicos.Add(examen);

                                        //Se crea en base de datos el examen vacío para luego agregarle valores metabólicos asociados a el.
                                        //historiarepo.GuardarTodo();
                                    }
                                    //Si el indicador no es el primero de un examen nuevo entonces se le asigna a la variable 'examen' la referencia del mismo
                                    else
                                    {
                                        examen = historia.Examenes_Metabolicos.Where(e => e.Fecha_Solicitud == fecha_solicitud).First();
                                    }

                                    //Se lee el código del indicador metabólico
                                    string codigo = linea.Substring(236, 6).Trim();

                                    //Si en efecto el indicador presente en la línea que se está leyendo existe se prosigue a anexarlos al examen
                                    if (indicadorrepo.ObtenerTodos().Where(i => i.Codigo == codigo).Count() != 0)
                                    {
                                        //Se carga el indicador con el que se está trabajando en una línea específica
                                        Indicador_Metabolico indicador = indicadorrepo.ObtenerTodos().Where(i => i.Codigo == codigo).First();

                                        //Se crea una nueva instancia de valor metabólico
                                        Valor_Metabolico val = new Valor_Metabolico();

                                        //Se obtienen los valores del indicador de la línea del archivo que se está leyendo
                                        string rango_alto = linea.Substring(194, 6).Trim();
                                        string rango_bajo = linea.Substring(188, 6).Trim();
                                        string unidades = linea.Substring(178, 10).Trim();
                                        bool alerta = false;
                                        string al = linea.Substring(200, 2).Trim();
                                        if (al != "")
                                            alerta = true;
                                        string valor = linea.Substring(118, 60).Trim();

                                        //Se inicializan los atributos del valor metabólico                                        
                                        //val.Examen_Metabolico_Id = examen.Id;
                                        //val.Indicador_Metabolico_Id = indicador.Id;
                                        val.Unidades = unidades;
                                        val.Rango_Alto = rango_alto;
                                        val.Rango_Bajo = rango_bajo;
                                        val.Valor = valor;
                                        val.Alerta = alerta;
                                        val.Indicador_Metabolico = indicador;
                                        examen.Valores_Metabolicos.Add(val);
                                        historiarepo.GuardarTodo();
                                    }
                                }
                            }
                            stream.Close();
                            file.MoveTo(Path.Combine(Server.MapPath("BackuplabtelFTP"), file.Name));
                        }
                    }
                       AsyncManager.Parameters["Error"] = false;
                }
                catch (Exception e)
                {
                    AsyncManager.Parameters["Error"] = true; 
                }
            }
            else
            {
                AsyncManager.Parameters["sinActualizacionesPendientes"] = true;
            }


             AsyncManager.OutstandingOperations.Decrement();
        }


         public ActionResult IndexCompleted(bool error, bool sinActualizacionesPendientes )
        {
            ViewData["sinActualizacionesPendientes"] = sinActualizacionesPendientes;
            ViewData["Error"] = error;
            return View();
        }

    }

А вот статья в MS, которая может вам помочь:

http://msdn.microsoft.com/en-us/library/ee728598.aspx

Надеюсь, это поможет!

...