异步控制器是一个可行的选择吗?

发布于 2024-11-17 18:04:43 字数 7938 浏览 2 评论 0原文

我目前有这段巨大而缓慢的代码,需要永远运行……我正在重构它,以使其更具可读性,并总体上提供更快的体验…… 基本上,我的服务器中有一个文件夹,其中存储了包含大量数据的文本文件。此脚本将从该文件中读取内容,并通过 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();
                }
            }

        }

我知道有一个称为异步控制器的功能,但我不确定它们是否适用于这种情况......

请给我一些关于如何做得更好的建议。

附注我还希望定期调用此脚本(每小时一次),但我也不知道如何调用..

I currently have this huge and slow code that takes forever to run.... Im in the process of refactoring it to make it somewhat more readable and overall provide a faster experience...
Basically I have a folder in my server where text files are stored with a LOT of data.. this script will read from this files and through EF add elements to the database... this takes a long time to load.

    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();
                }
            }

        }

I know there is a feature called asynchronous controllers but Im not sure if they are meant for this case...

Please give me some advice on how to make this better.

ps. I would also like this script to be called regularly (once an hour) but Im not sure how to that either..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巾帼英雄 2024-11-24 18:04:43

这需要在MVC中完成吗?看起来这可能可以通过 Windows 服务(这可能有点麻烦)或其他类型的计划应用程序,甚至可能是控​​制台应用程序来完成。对于仅使用文件系统或数据库执行操作的重复任务,我使用使用 System.Threading.Timers 的控制台应用程序。你让后台计时器线程工作,你的网络应用程序可以自由地做网络事情:)

如果它需要基于网络,这里有一篇关于如何执行简单的重复任务的方便帖子。

https://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< /a>

希望这有帮助!

Does this need to be done in MVC? It seems like this could maybe be done by something like a windows service (which could be kind of a pain) or some other kind of scheduled app, maybe even a console application. For repeating tasks that just do things with either file systems or the DB, I use a console application that uses System.Threading.Timers. You let the background timer threads work and your web app is free to do, well, web things :)

If it needs to be web based, here's a handy post for how to do simple repeating tasks.

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

If you wanted to turn your action into an asynchronous action then your controller would look something like this:

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();
        }

    }

And here's the MS article that could help you out:

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

Hope this helps!

情释 2024-11-24 18:04:43

检查一下它可能会有所帮助 http://quartznet.sourceforge.net/ 。我计划在当前的项目中使用它来安排一些长时间运行的任务。

Check this out it may help http://quartznet.sourceforge.net/ . I plan on using it in my current project to schedule up some longer running tasks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文