私は現在、この巨大で低速なコードを持っています。私はいつも実行するのに時間がかかります。私はそれをいくらか読みやすく、全体的により速い経験を提供するためにリファクタリングする過程にあります... 基本的に私は私のサーバテキストファイルには多くのデータが格納されています。このスクリプトはこのファイルから読み込み、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。私はこのスクリプトを定期的に(1時間に1回)呼びたいと思っていますが、その方法もわかりません。
私はオプションだと思いますが、asyncControllerという機能があることを考えれば、この方法を改善するには良いアプローチかもしれないと思いました。 – ignaciofuentes
長時間実行しているプロセスであれば、非同期で処理する方が間違いなく良いでしょう。 MSからの助言は次のとおりです。 操作は、CPUバインドの代わりにネットワークバインドまたはI/Oバインドされています。 テストでは、ブロック操作がサイトのパフォーマンスのボトルネックとなり、IISがこれらのブロッキング呼び出しに対して非同期アクションメソッドを使用してさらに多くの要求を処理できることが示されています。 並列性はコードの単純さよりも重要です。 長時間実行している要求をユーザーがキャンセルできるようにするメカニズムを提供する必要があります。 – mymex1
それから私の質問は..私はそれをどうやってやるのだろう? – ignaciofuentes