我一直在从foreach循环内启动的大量进程中捕获标准错误。这样可以很好地工作,并且可以返回正确数量的异常。当我尝试使用Parallel.ForEach()时,它仅返回50%的异常。
调用LaunchProcessHandler的Parallel.ForEach
public ConcurrentBag<IO_Exception_Check_Result> RunCheck()
{
List<string> array = JsonConvert.DeserializeObject<List<string>>(System.IO.File.ReadAllText(testInputPath));
ConcurrentBag<IO_Exception_Check_Result> results = new ConcurrentBag<IO_Exception_Check_Result>();
StringBuilder stdoutxTemp = new StringBuilder();
StringBuilder stderrxTemp = new StringBuilder();
Parallel.ForEach(array, item =>
{
StringBuilder stdoutx = new StringBuilder();
StringBuilder stderrx = new StringBuilder();
Process process = LauchProcessHandler(ref stdoutx, ref stderrx);
for (int i = 0; i < 20; i++)
{
process.StandardInput.WriteLine(item);
}
try
{
if (!process.WaitForExit(timeout))
{
process.Kill();
}
}
catch
{
Console.WriteLine("Process already killed");
}
if (!string.IsNullOrEmpty(stderrx.ToString()))
{
results.Add(new IO_Exception_Check_Result(item, stdoutx.ToString(), stderrx.ToString()));
}
});
return results;
LaunchProcessHandler方法,该方法被调用以启动启动进程。
private Process LauchProcessHandler(ref StringBuilder stdoutxParam, ref StringBuilder stderrxParam)
{
StringBuilder stdoutx = new StringBuilder();
StringBuilder stderrx = new StringBuilder();
ProcessStartInfo startInfo = new ProcessStartInfo
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
};
if (LocalUseDotnetCLI)
{
startInfo.FileName = "dotnet";
startInfo.Arguments = $"run --project {appPath} {arguments}";
//startInfo.WorkingDirectory = startInfo.Arguments;
}
else
{
startInfo.FileName = appPath;
startInfo.Arguments = arguments;
}
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.OutputDataReceived += (object sender, System.Diagnostics.DataReceivedEventArgs e) => stdoutx.Append(e.Data);
process.ErrorDataReceived += (object sender, System.Diagnostics.DataReceivedEventArgs e) => stderrx.Append(e.Data);
process.BeginOutputReadLine();
process.BeginErrorReadLine();
stdoutxParam = stdoutx;
stderrxParam = stderrx;
return process;
}
如果有比使用Parallel.ForEach()更好的解决方案来提高性能,我也会对此感兴趣。