当我在WPF应用程序中使用Task.Run运行进程时,我遇到了触发Process.Exited事件的问题。 如果由于进程类限制而导致此Exited事件超出问题,我想在任务完成时更新TextBox.Text。 我没有运气也尝试过ContinueWith
async private void Select_Click(object sender, RoutedEventArgs e)
{
CancellationToken ct = new CancellationToken();
CancellationTokenSource cts = new CancellationTokenSource();
FolderBrowserDialog diag;
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
Notification.Text = string.Empty;
diag = new FolderBrowserDialog();
var result = diag.ShowDialog();
var istest = TestMode.IsChecked == true;
if (result == System.Windows.Forms.DialogResult.OK)
{
var path = diag.SelectedPath;
await Task.Run(() =>
{
var processStartInfo = new ProcessStartInfo()
{
FileName = "cmd.exe",
WindowStyle = ProcessWindowStyle.Hidden,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = true
};
var command="ping yahoo.com";
var process = new Process() { StartInfo = processStartInfo, EnableRaisingEvents = true };
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.StandardInput.WriteLineAsync(command);
process.ErrorDataReceived += (p, @event) =>
{
Dispatcher.InvokeAsync(() =>
{
Notification.AppendText(String.Format("Error {0} {1}", @event.Data, Environment.NewLine));
}, System.Windows.Threading.DispatcherPriority.Background);
};
process.OutputDataReceived += (p, @event) =>
{
Dispatcher.InvokeAsync(() =>
{
Notification.AppendText(@event.Data + Environment.NewLine);
}, System.Windows.Threading.DispatcherPriority.Background);
};
process.WaitForExit();
process.Exited += (@Sender, args) =>
{
tcs.SetResult(process);
System.Windows.MessageBox.Show("Done");
process.Dispose();
};
});
}
}
所有其他事件都没有任何问题被解雇。 谢谢
答案 0 :(得分:3)
在订阅WaitForExit
事件之前调用Exited
,因此线程将在那里等待,直到进程退出,并且在进程退出之前从不订阅事件。当WaitForExit
返回进程已经退出时,只有您订阅了永远不会再触发的Exited
事件。
因此,在致电Exited
之前订阅WaitForExit
个事件。
process.Exited += (@Sender, args) =>
{
tcs.SetResult(process);
System.Windows.MessageBox.Show("Done");
process.Dispose();
};
process.WaitForExit();