Fix DDC/CI timeout using Task.WhenAny
Previous timeout using CancellationToken didn't work because ReadToEndAsync blocks waiting for process output. Now using Task.WhenAny with Task.Delay to properly timeout and kill hung processes after 5 seconds. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,9 +13,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>1.0.13</Version>
|
<Version>1.0.14</Version>
|
||||||
<AssemblyVersion>1.0.13.0</AssemblyVersion>
|
<AssemblyVersion>1.0.14.0</AssemblyVersion>
|
||||||
<FileVersion>1.0.13.0</FileVersion>
|
<FileVersion>1.0.14.0</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -28,18 +28,17 @@ internal class ConsoleHelper
|
|||||||
p.StartInfo.FileName = command;
|
p.StartInfo.FileName = command;
|
||||||
p.Start();
|
p.Start();
|
||||||
|
|
||||||
using var cts = new CancellationTokenSource(timeoutMs);
|
var readTask = p.StandardOutput.ReadToEndAsync();
|
||||||
try
|
var completedTask = await Task.WhenAny(readTask, Task.Delay(timeoutMs));
|
||||||
|
|
||||||
|
if (completedTask != readTask)
|
||||||
{
|
{
|
||||||
var output = await p.StandardOutput.ReadToEndAsync(cts.Token);
|
// Timeout - kill the process
|
||||||
await p.WaitForExitAsync(cts.Token);
|
try { p.Kill(true); } catch { }
|
||||||
return output;
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
try { p.Kill(); } catch { }
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return await readTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<string> CmdCommandAsync(params string[] cmds) =>
|
public static async Task<string> CmdCommandAsync(params string[] cmds) =>
|
||||||
@@ -63,23 +62,28 @@ internal class ConsoleHelper
|
|||||||
}
|
}
|
||||||
p.StandardInput.WriteLine("exit");
|
p.StandardInput.WriteLine("exit");
|
||||||
|
|
||||||
using var cts = new CancellationTokenSource(timeoutMs);
|
var readTask = Task.Run(async () =>
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var result = await p.StandardOutput.ReadToEndAsync(cts.Token);
|
var result = await p.StandardOutput.ReadToEndAsync();
|
||||||
var error = await p.StandardError.ReadToEndAsync(cts.Token);
|
var error = await p.StandardError.ReadToEndAsync();
|
||||||
if (!string.IsNullOrWhiteSpace(error))
|
if (!string.IsNullOrWhiteSpace(error))
|
||||||
result = result + "\r\n<Error Message>:\r\n" + error;
|
result = result + "\r\n<Error Message>:\r\n" + error;
|
||||||
await p.WaitForExitAsync(cts.Token);
|
|
||||||
p.Close();
|
|
||||||
Debug.WriteLine(result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
});
|
||||||
catch (OperationCanceledException)
|
|
||||||
|
var completedTask = await Task.WhenAny(readTask, Task.Delay(timeoutMs));
|
||||||
|
|
||||||
|
if (completedTask != readTask)
|
||||||
{
|
{
|
||||||
try { p.Kill(); } catch { }
|
// Timeout - kill the process
|
||||||
|
try { p.Kill(true); } catch { }
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var output = await readTask;
|
||||||
|
p.Close();
|
||||||
|
Debug.WriteLine(output);
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Command(string fileName, params string[] cmds)
|
public static string Command(string fileName, params string[] cmds)
|
||||||
|
|||||||
Reference in New Issue
Block a user