How to cancel a async task that starts a process in C#?

戏子无情 提交于 2019-12-11 06:18:43

问题


Currently my code runs a checkout from svn and redirections the stdout and stderr to a textbox using two tasks as seen below. I want to be able to cancel the task immediately when a user clicks the StopButton and be able to cancel the download. I understand that if I changed my cmd.exe command to say something such as "Pause", which continues to run until a user clicks something, I can cancel this command with the StopButton. I am very new to C# and trying to understand why I can cancel that command and not the svn download.

Is this a way I should be implementing my code or should I try a different method?

Thanks so much for the help! I truly appreciate it!

   public Form2()
    {
        InitializeComponent();

    }

    private TaskCompletionSource<bool> _cancelTask;

    private async Task RunProcess()
    {
        Process process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "cmd.exe",
                Arguments = "svn download"
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = false,
            }
        };


        Console.Write(URL);
        process.Start();

        Task readerTasks = Task.WhenAll(
            ConsumeReader(process.StandardError),
            ConsumeReader(process.StandardOutput));

        Task completedTask = await Task.WhenAny(readerTasks, _cancelTask.Task);

        if(completedTask == _cancelTask.Task)
        {
            process.Kill();
            await readerTasks;
            throw new TaskCanceledException(_cancelTask.Task);
        }
    }

    private async Task ConsumeReader(TextReader reader)
    {
        char[] text = new char[512];
        int cch;

        while ((cch = await reader.ReadAsync(text, 0, text.Length)) > 0)
        {
            textBox2.AppendText(new string(text, 0, cch));
        }
    }

    private async void Submit_Click(object sender, EventArgs e)
    {

        Submit.Enabled = false;
        StopButton.Enabled = true;
        _cancelTask = new TaskCompletionSource<bool>();

        try
        {
            await RunProcess(cts.Token);
        }
        catch (OperationCanceledException)
        {
            MessageBox.Show("The operation was cancelled");
        }
        finally
        {
            _cancelTask = null;
            Submit.Enabled = true;
            StopButton.Enabled = false;
        }
    }

    private void StopButton_Click(object sender, EventArgs e)
    {
        _cancelTask.SetCanceled();
    }

回答1:


I found a solution, not sure if this is the best, but you can start another process to start the command line command taskkill to kill all of the .exe's that are running. I now kill the cmd.exe (parent) and the svn.exe (child) that was called from the cmd.exe!

This is only useful if you know the .exes that are started from the parent if there were many more children created it would be best to find a different solution to recursively go and find the children processes.

    if(completedTask == _cancelTask.Task)
    {
        //process.Kill(); This would only kill the CMD.exe
        Process exit = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "cmd.exe",
                    //Arguments = "/K Pause",
                    Arguments = "/C taskkill /f /im svn.exe & taskkill /f /im cmd.exe",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = false,
                }
            };
            exit.Start();
        await readerTasks;
        throw new TaskCanceledException(_cancelTask.Task);
    }


来源:https://stackoverflow.com/questions/38903661/how-to-cancel-a-async-task-that-starts-a-process-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!