我目前有这个庞大而缓慢的代码需要永远运行....我正在重构它以使其更具可读性并且整体提供更快的体验... 基本上我在我的服务器中有一个文件夹,其中存储有大量数据的文本文件..这个脚本将从这些文件读取并通过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();
}
}
}
我知道有一个叫做异步控制器的功能,但我不确定它们是否适用于这种情况......
请给我一些关于如何做得更好的建议。
PS。我也希望定期调用这个脚本(每小时一次),但我不确定如何...
答案 0 :(得分:0)
这是否需要在MVC中完成?看起来这可能是通过像Windows服务(可能是一种痛苦)或其他类型的预定应用程序,甚至可能是控制台应用程序。对于重复只使用文件系统或数据库执行操作的任务,我使用一个使用System.Threading.Timers的控制台应用程序。您让后台计时器线程工作,您的Web应用程序可以自由地执行以下操作:)
如果需要基于网络,这里有一个方便的帖子,介绍如何进行简单的重复任务。
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
希望这有帮助!
答案 1 :(得分:0)
检查一下它可能对http://quartznet.sourceforge.net/有所帮助。我打算在我当前的项目中使用它来安排一些更长时间运行的任务。