C# 方法中的多个进程从调用线程异步执行
假设我有多个(比如说,两个)进程,我想顺序但异步地运行,我该怎么做呢?请参阅下面的代码片段:C# 方法中的多个进程从调用线程异步执行,c#,asynchronous,process,task,C#,Asynchronous,Process,Task,假设我有多个(比如说,两个)进程,我想顺序但异步地运行,我该怎么做呢?请参阅下面的代码片段: public virtual Task<bool> ExecuteAsync() { var tcs = new TaskCompletionSource<bool>(); string exe1 = Spec.GetExecutablePath1(); string exe2 = Spec.GetExecutablePath2(); string
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;
}
当我只使用第一个进程运行代码时(删除与另一个进程相关的所有代码),它运行正常。您看到的错误与这两个进程无关。这是由于多次设置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;
}
公共虚拟任务ExecuteAsync()
{
var tcs=new TaskCompletionSource();
字符串exe1=Spec.GetExecutablePath1();
字符串exe2=Spec.GetExecutablePath2();
字符串args1=string.Format(“--input1={0}--input2={1}”,input1,input2);
字符串args2=string.Format(“--input1={0}--input2={1}”,input1,input2);
尝试
{
var process1=新流程
{
EnableRaisingEvents=true,
StartInfo=
{
UseShellExecute=false,
FileName=exe1,
参数=args1,
重定向标准输出=真,
RedirectStandardError=true,
WorkingDir=CaseDir
}
};
var process2=新流程
{
EnableRaisingEvents=true,
StartInfo=
{
UseShellExecute=false,
FileName=exe2,
参数=args2,
重定向标准输出=真,
RedirectStandardError=true,
WorkingDir=CaseDir
}
};
process1.退出+=(发送方,参数)=>
{
if(process1.ExitCode!=0)
{
string errorMessage=process1.StandardError.ReadToEndAsync();
tcs.SetResult(假);
tcs.SetException(新的InvalidOperationException(“进程1未正确退出。错误消息:“+errorMessage”);
}
其他的
{
WriteAllText(日志文件,process1.StandardOutput.ReadToEnd());
process2.Start();
}
process1.Dispose();
};
process2.退出+=(发送方,参数)=>
{
if(process2.ExitCode!=0)
{
string errorMessage=process2.StandardError.ReadToEndAsync();
tcs.SetResult(假);
tcs.SetException(新的InvalidOperationException(“进程2未正确退出。错误消息:“+errorMessage”);
}
其他的
{
WriteAllText(日志文件,process2.StandardOutput.ReadToEnd());
tcs.SetResult(真);
}
process2.Dispose();
};
process1.Start();
}
捕获(例外e)
{
Logger.InfoOutputWindow(e.Message);
tcs.SetResult(假);
返回tcs.Task;
}
返回tcs.Task;
}
您看到的错误与这两个进程无关。它是由多次设置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;
}
公共虚拟任务ExecuteAsync()
{
var tcs=new TaskCompletionSource();
字符串exe1=Spec.GetExecutablePath1();
字符串exe2=Spec.GetExecutablePath2();
字符串args1=string.Format(“--input1={0}--input2={1}”,input1,input2);
字符串args2=string.Format(“--input1={0}--input2={1}”,input1,input2);
尝试
{
var process1=新流程
{
EnableRaisingEvents=true,
StartInfo=
{
UseShellExecute=false,
FileName=exe1,
参数=args1,
重定向标准输出=真,
RedirectStandardError=true,
WorkingDir=CaseDir
}
};
var process2=新流程
{
EnableRaisingEvents=true,
StartInfo=
{
UseShellExecute=false,
FileName=exe2,
参数=args2,
重定向标准输出=真,
RedirectStandardError=true,
WorkingDir=CaseDir
}
};