[英]Multiple processes in method executed asynchronously from calling thread
假設我有多個(例如兩個)進程要順序但異步運行,我該如何去做? 請參見下面的代碼段:
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".
當我只用第一個進程運行代碼(刪除與另一個進程有關的所有代碼)時,它運行正常。
您看到的錯誤與這兩個過程無關。 這是由於多次設置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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.