Điều gì có thể là lý do của quá trình của tôi treo trong khi chờ thoát?
Mã này phải khởi động tập lệnh powershell, bên trong thực hiện nhiều hành động, ví dụ: bắt đầu biên dịch lại mã qua MSBuild, nhưng có lẽ vấn đề là nó tạo ra quá nhiều đầu ra và mã này bị kẹt trong khi chờ thoát ngay cả khi tập lệnh shell power được thực thi chính xác
nó hơi "lạ" vì đôi khi mã này hoạt động tốt và đôi khi nó bị kẹt.
Mã treo tại:
process.WaitForExit (ProcessTimeOutMiliseconds);
Kịch bản Powershell thực thi trong khoảng 1-2 giây trong khi thời gian chờ là 19 giây.
public static (bool Success, string Logs) ExecuteScript(string path, int ProcessTimeOutMiliseconds, params string[] args)
{
StringBuilder output = new StringBuilder();
StringBuilder error = new StringBuilder();
using (var outputWaitHandle = new AutoResetEvent(false))
using (var errorWaitHandle = new AutoResetEvent(false))
{
try
{
using (var process = new Process())
{
process.StartInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "powershell.exe",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
Arguments = $"-ExecutionPolicy Bypass -File \"{path}\"",
WorkingDirectory = Path.GetDirectoryName(path)
};
if (args.Length > 0)
{
var arguments = string.Join(" ", args.Select(x => $"\"{x}\""));
process.StartInfo.Arguments += $" {arguments}";
}
output.AppendLine($"args:'{process.StartInfo.Arguments}'");
process.OutputDataReceived += (sender, e) =>
{
if (e.Data == null)
{
outputWaitHandle.Set();
}
else
{
output.AppendLine(e.Data);
}
};
process.ErrorDataReceived += (sender, e) =>
{
if (e.Data == null)
{
errorWaitHandle.Set();
}
else
{
error.AppendLine(e.Data);
}
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit(ProcessTimeOutMiliseconds);
var logs = output + Environment.NewLine + error;
return process.ExitCode == 0 ? (true, logs) : (false, logs);
}
}
finally
{
outputWaitHandle.WaitOne(ProcessTimeOutMiliseconds);
errorWaitHandle.WaitOne(ProcessTimeOutMiliseconds);
}
}
}
Kịch bản:
start-process $args[0] App.csproj -Wait -NoNewWindow
[string]$sourceDirectory = "\bin\Debug\*"
[int]$count = (dir $sourceDirectory | measure).Count;
If ($count -eq 0)
{
exit 1;
}
Else
{
exit 0;
}
Ở đâu
$args[0] = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe"
Biên tập
Để giải pháp của @ ingen, tôi đã thêm trình bao bọc nhỏ thử lại để thực thi MS Build bị treo
public static void ExecuteScriptRx(string path, int processTimeOutMilliseconds, out string logs, out bool success, params string[] args)
{
var current = 0;
int attempts_count = 5;
bool _local_success = false;
string _local_logs = "";
while (attempts_count > 0 && _local_success == false)
{
Console.WriteLine($"Attempt: {++current}");
InternalExecuteScript(path, processTimeOutMilliseconds, out _local_logs, out _local_success, args);
attempts_count--;
}
success = _local_success;
logs = _local_logs;
}
Trong trường hợp InternalExecuteScriptlà mã ingen của
Rxcách tiếp cận đó có hiệu quả (như trong thời gian không hết thời gian) ngay cả với quá trình MSBuild đi lạc nằm xung quanh dẫn đến sự chờ đợi vô thời hạn? quan tâm để biết làm thế nào đã được xử lý