Ayer me surgió un pequeño problema. En una máquina de recursos limitados y desantendida una de las aplicaciones que debían funcionar se quedó colgada por un fallo de red (consumiendo todos los recursos que encontró en la máquina), dejando esta máquina casi inoperativa. Para solucionar esto me acordé que .NET trae una seria de clases para gestionar los procesos del sistema. Haciendo una búsqueda rápida por Internet di con lo que quería, consultar la lista de procesos del sistema, y si alguno ocupa más de una cantidad de memoria (en nuestro entorno una única aplicación), cerrarla (de volverla a abrir se encarga otro proceso de otra aplicación).
Para obtener la lista de procesos usé este método (se muestra la información en un ListView)
listView.Items.Clear();
Process[] processList = Process.GetProcesses();
foreach (Process process in processList)
{
ListViewItem item = new ListViewItem(process.Id.ToString());
item.SubItems.Add(process.ProcessName);
long totalBytesOfMemoryUsed = process.WorkingSet64;
long totalKyloBytesOfMemoryUsed = totalBytesOfMemoryUsed / 1024;
System.Globalization.NumberFormatInfo formatInfo = new System.Globalization.NumberFormatInfo();
formatInfo.NumberGroupSeparator = ".";
formatInfo.NumberDecimalDigits = 0;
item.SubItems.Add(string.Format(formatInfo, "{0:N} KB", totalKyloBytesOfMemoryUsed));
listView.Items.Add(item);
}
Puse un Timer en mi aplicación que se disparara cada minutos, y haciendo uso del código anterior hice lo que necesitaba
Process[] processList = Process.GetProcesses();
foreach (Process process in processList)
{
long totalBytesOfMemoryUsed = process.WorkingSet64;
long totalKyloBytesOfMemoryUsed = totalBytesOfMemoryUsed / 1024;
if (totalKyloBytesOfMemoryUsed > (64 * 1024)) // Mas de 64MB
{
textBox.AppendText(string.Format("Proceso {0} ({1}) supera el umbral {2}", process.Id, process.ProcessName, System.Environment.NewLine));
}
}
Para cerrar (matar) el proceso use estas funciones
private void KillById(int id)
{
Process process = Process.GetProcessById(id);
process.Kill();
}
private void KillByName(string processName)
{
Process[] processList = Process.GetProcessesByName(processName);
foreach (Process process in processList)
{
process.Kill();
}
}Con esto, quedo resuelto mi problema. Como mejora se me ocurre, pasar esta aplicación a un servicio del sistema, pero eso lo dejaré para la siguiente versión de la aplicación.