Улучшил RemiteCompiler - убрал утечки по совету DeepSeek

This commit is contained in:
Mikhalkovich Stanislav 2026-01-15 10:07:23 +03:00
parent 9b3937cb03
commit f5557fc8cf
3 changed files with 68 additions and 11 deletions

View file

@ -88,7 +88,7 @@ namespace PascalABCCompiler
public const int sendCommandStartNumber = 100; public const int sendCommandStartNumber = 100;
public volatile CompilerState compilerState = CompilerState.Reloading; // PVS 01/2022 volatile public volatile CompilerState compilerState = CompilerState.Reloading; // PVS 01/2022 volatile
Encoding inputEncoding = System.Text.Encoding.UTF8; Encoding inputEncoding = System.Text.Encoding.UTF8;
bool compilationSatarted = false; bool compilationStarted = false;
public int MaxProcessMemoryMB public int MaxProcessMemoryMB
{ {
@ -213,9 +213,9 @@ namespace PascalABCCompiler
void ChangeCompilerState(CompilerState State, string FileName) void ChangeCompilerState(CompilerState State, string FileName)
{ {
if (State == CompilerState.Ready && compilationSatarted) if (State == CompilerState.Ready && compilationStarted)
{ {
compilationSatarted = false; compilationStarted = false;
if (CheckProcessMemory()) if (CheckProcessMemory())
return; return;
} }
@ -224,7 +224,7 @@ namespace PascalABCCompiler
OnChangeCompilerState(this, State, FileName); OnChangeCompilerState(this, State, FileName);
} }
void stopCompiler() /*void stopCompiler()
{ {
try try
{ {
@ -243,6 +243,31 @@ namespace PascalABCCompiler
pabcnetcProcess = null; pabcnetcProcess = null;
remoteCompilerWorkingSet = 0; remoteCompilerWorkingSet = 0;
} }
}*/
// SSM 09/01/26 - по совету DeepSeek добавил WaitForExit(10) и Dispose() чтобы освободить ресурсы
void stopCompiler()
{
try
{
if (pabcnetcProcess != null && !pabcnetcProcess.HasExited)
{
pabcnetcProcess.EnableRaisingEvents = false;
if (pabcnetcStreamReader != null)
pabcnetcStreamReader.Remove(inputId);
pabcnetcProcess.Kill();
pabcnetcProcess.WaitForExit(10);
pabcnetcProcess.Dispose(); // ← ЕДИНСТВЕННОЕ ДОБАВЛЕНИЕ
}
}
catch
{
}
pabcnetcProcess = null;
remoteCompilerWorkingSet = 0;
} }
@ -403,19 +428,20 @@ namespace PascalABCCompiler
} }
public delegate void EnvorimentIdleDelegate(); public delegate void EnvironmentIdleDelegate();
public event EnvorimentIdleDelegate EnvorimentIdle; public event EnvironmentIdleDelegate EnvironmentIdle;
void waitCompilerReloading() void waitCompilerReloading()
{ {
while (compilerReloading) while (compilerReloading)
{ {
Thread.Sleep(5); Thread.Sleep(5);
if (EnvorimentIdle != null) if (EnvironmentIdle != null)
EnvorimentIdle(); EnvironmentIdle();
} }
} }
public string Compile() public string Compile()
{ {
errorsList.Clear(); errorsList.Clear();
@ -423,14 +449,36 @@ namespace PascalABCCompiler
//sendObject(ConsoleCompilerConstants.InternalDebug, internalDebug); //sendObject(ConsoleCompilerConstants.InternalDebug, internalDebug);
//sendObject(ConsoleCompilerConstants.CompilerOptions, compilerOptions); //sendObject(ConsoleCompilerConstants.CompilerOptions, compilerOptions);
waitCompilerReloading(); waitCompilerReloading();
sendCompilerOptions(); sendCompilerOptions();
compilerState = CompilerState.CompilationStarting; compilerState = CompilerState.CompilationStarting;
compilationSatarted = true; compilationStarted = true;
sendCommand(ConsoleCompilerConstants.CommandCompile); sendCommand(ConsoleCompilerConstants.CommandCompile);
const int timeoutSeconds = 30;
DateTime startTime = DateTime.Now;
int checkCounter = 0;
while (compilerState != CompilerState.Ready) while (compilerState != CompilerState.Ready)
Thread.Sleep(5); {
if (checkCounter++ % 50 == 0) // 1000ms / 20ms = 50 - чтобы не вызывать дорогую DateTime.Now
{
if ((DateTime.Now - startTime).TotalSeconds > timeoutSeconds)
{
// ТАЙМАУТ! Компилятор не ответил за 30 секунд
errorsList.Add(new RemoteCompilerInternalError(
$"Таймаут компиляции ({timeoutSeconds} секунд). " +
"Компилятор не отвечает."));
Reload(); // Перезапускаем компилятор (он вероятно завис)
return null;
}
}
Thread.Sleep(20); // SSM 09.01.26 - изменил - было 5 мс - большая нагрузка на систему
}
if (errorsList.Count > 0) if (errorsList.Count > 0)
return null; return null;
return compilerOptions.OutputFileName; return compilerOptions.OutputFileName;
@ -463,7 +511,7 @@ namespace PascalABCCompiler
warnings.Clear(); warnings.Clear();
waitCompilerReloading(); waitCompilerReloading();
sendCompilerOptions(); sendCompilerOptions();
compilationSatarted = true; compilationStarted = true;
sendCommand(ConsoleCompilerConstants.CommandCompile); sendCommand(ConsoleCompilerConstants.CommandCompile);
} }

View file

@ -11258,6 +11258,15 @@ begin
end; end;
end; end;
/// Возвращает первый элемент, удовлетворяющий условию, или значение по умолчанию, если ни одного такого элемента не найдено
function FirstOrDefault<T>(self: sequence of T; pred: T -> boolean; defaultValue: T): T; extensionmethod;
begin
foreach var item in self do
if pred(item) then
Exit(item);
Result := defaultValue;
end;
/// Возвращает произведение элементов последовательности /// Возвращает произведение элементов последовательности
function Product(Self: sequence of real): real; extensionmethod; function Product(Self: sequence of real): real; extensionmethod;
begin begin

Binary file not shown.