process.在任务运行时未达到未达到[英] Process.Exited not reached when running in Task.Run

本文是小编为大家收集整理的关于process.在任务运行时未达到未达到的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

本文来自:IT宝库(https://www.itbaoku.cn)

我在使用task.run中运行该过程时,在WPF应用程序中运行该过程时遇到了问题. 如果由于过程类限制而导致此事件取消了此事件,那么我想在任务完成后更新textbox.text. 我尝试继续没有运气

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();
                };
            });

        }

    }

所有其他事件都被解雇而没有任何问题. 谢谢你

推荐答案

您呼叫WaitForExit在您订阅Exited事件之前,线程将在此等待直到过程退出,并且在过程退出之前永远不会订阅事件.当WaitForExit返回过程已经退出时,只有您订阅Exited事件将永远不会再次触发.

SO订阅Exited呼叫之前的事件WaitForExit.

process.Exited += (@Sender, args) =>
{
    tcs.SetResult(process);
    System.Windows.MessageBox.Show("Done");
    process.Dispose();
};
process.WaitForExit();

本文地址:https://www.itbaoku.cn/post/2814394.html

问题描述

I am having a problem getting the Process.Exited event to fire when I run the process using a Task.Run in a WPF app. If this getting this Exited event is out of the questions due to the process class limitation, I would like to to update the TextBox.Text when the task is complete. I tried ContinueWith without any luck either

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();
                };
            });

        }

    }

All of the other events are getting fired without any problems. Thank you

推荐答案

You call WaitForExit before you subscribe Exited event, so thread will wait there till process exits and never subscribes the event before the process exits. When WaitForExit returns process is already exited, then only you subscribe Exited event which is never going to fire again.

So subscribe Exited event before you call WaitForExit.

process.Exited += (@Sender, args) =>
{
    tcs.SetResult(process);
    System.Windows.MessageBox.Show("Done");
    process.Dispose();
};
process.WaitForExit();