假设我有多个(比方说,两个)进程,我想按顺序但异步运行,我该怎么做呢?请参阅以下代码段:
public virtual Task<bool> ExecuteAsync()
{
var tcs = new TaskCompletionSource<bool>();
string exe1 = Spec.GetExecutablePath1();
string exe2 = Spec.GetExecutablePath2();
string args1 = string.Format("--input1={0} --input2={1}", Input1, Input2);
string args2 = string.Format("--input1={0} --input2={1}", Input1, Input2);
try
{
var process1 = new Process
{
EnableRaisingEvents = true,
StartInfo =
{
UseShellExecute = false,
FileName = exe1,
Arguments = args1,
RedirectStandardOutput = true,
RedirectStandardError = true,
WorkingDir = CaseDir
}
};
var process2 = new Process
{
EnableRaisingEvents = true,
StartInfo =
{
UseShellExecute = false,
FileName = exe2,
Arguments = args2,
RedirectStandardOutput = true,
RedirectStandardError = true,
WorkingDir = CaseDir
}
};
process1.Exited += (sender, arguments) =>
{
if (process1.ExitCode != 0)
{
string errorMessage = process1.StandardError.ReadToEndAsync();
tcs.SetResult(false);
tcs.SetException(new InvalidOperationException("The process1 did not exit correctly. Error message: " + errorMessage));
}
else
{
File.WriteAllText(LogFile, process1.StandardOutput.ReadToEnd());
tcs.SetResult(true);
}
process1.Dispose();
};
process1.Start();
process2.Exited += (sender, arguments) =>
{
if (process2.ExitCode != 0)
{
string errorMessage = process2.StandardError.ReadToEndAsync();
tcs.SetResult(false);
tcs.SetException(new InvalidOperationException("The process2 did not exit correctly. Error message: " + errorMessage));
}
else
{
File.WriteAllText(LogFile, process2.StandardOutput.ReadToEnd());
tcs.SetResult(true);
}
process2.Dispose();
};
process2.Start();
}
catch (Exception e)
{
Logger.InfoOutputWindow(e.Message);
tcs.SetResult(false);
return tcs.Task;
}
return tcs.Task;
}
}
提前感谢您的想法。
编辑#1:
当我运行上面显示的代码时,在成功完成第一个过程后失败,并显示以下错误:
"System.InvalidOperationException; An attempt was made to transition a task to a final state when it had already completed".
当我仅使用第一个进程运行代码(删除所有与另一个进程相关的代码)时,它运行正常。
答案 0 :(得分:2)
您看到的错误与这两个进程无关。它是由多次设置TaskCompletionSource的SetResult方法引起的。你不能给同一个任务两个不同的结果。
有一些重要的变化:
这是未经测试的,但您的代码最终应该看起来像这样:
public virtual Task<bool> ExecuteAsync()
{
var tcs = new TaskCompletionSource<bool>();
string exe1 = Spec.GetExecutablePath1();
string exe2 = Spec.GetExecutablePath2();
string args1 = string.Format("--input1={0} --input2={1}", Input1, Input2);
string args2 = string.Format("--input1={0} --input2={1}", Input1, Input2);
try
{
var process1 = new Process
{
EnableRaisingEvents = true,
StartInfo =
{
UseShellExecute = false,
FileName = exe1,
Arguments = args1,
RedirectStandardOutput = true,
RedirectStandardError = true,
WorkingDir = CaseDir
}
};
var process2 = new Process
{
EnableRaisingEvents = true,
StartInfo =
{
UseShellExecute = false,
FileName = exe2,
Arguments = args2,
RedirectStandardOutput = true,
RedirectStandardError = true,
WorkingDir = CaseDir
}
};
process1.Exited += (sender, arguments) =>
{
if (process1.ExitCode != 0)
{
string errorMessage = process1.StandardError.ReadToEndAsync();
tcs.SetResult(false);
tcs.SetException(new InvalidOperationException("The process1 did not exit correctly. Error message: " + errorMessage));
}
else
{
File.WriteAllText(LogFile, process1.StandardOutput.ReadToEnd());
process2.Start();
}
process1.Dispose();
};
process2.Exited += (sender, arguments) =>
{
if (process2.ExitCode != 0)
{
string errorMessage = process2.StandardError.ReadToEndAsync();
tcs.SetResult(false);
tcs.SetException(new InvalidOperationException("The process2 did not exit correctly. Error message: " + errorMessage));
}
else
{
File.WriteAllText(LogFile, process2.StandardOutput.ReadToEnd());
tcs.SetResult(true);
}
process2.Dispose();
};
process1.Start();
}
catch (Exception e)
{
Logger.InfoOutputWindow(e.Message);
tcs.SetResult(false);
return tcs.Task;
}
return tcs.Task;
}