Убить упрямую задачу из C # WinForm - PullRequest
0 голосов
/ 07 марта 2012

Я использую ac # winform, которая открывает командный файл.Я хочу, чтобы пользователь мог нажать на кнопку «Стоп» в winform и убить эту задачу.Проблема в том, что winform зависает до тех пор, пока запуск пакетного файла не будет полностью завершен.Поэтому я использовал фонового работника (который позволил мне открыть новый поток, который не беспокоит функциональность winform):

    private void bgw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        string fileName = (string)e.Argument;
        ExecuteTest(fileName);
    }

и заметил, что я добираюсь до «отладки!»сообщение, но командный процесс не умирает:

    private void tsbStopRun_Click(object sender, EventArgs e)
    {
        Process prc1 = GetProcess("cmd");
        KillProcess(prc1);
    }

    private Process GetProcess(string processName) 
    {
        Process[] Prc = Process.GetProcessesByName(processName);
        if (Prc.Length > 0)
            return Prc[0]; 
        else 
            return null; 
    }

    private void KillProcess(Process prc)
    {
        if (prc != null)
        {
            prc.Kill();  
            MessageBox.Show("debug!");
        }
    }

Кстати, если я открою командную задачу и нажму на кнопку остановки, командная задача будет уничтожена ...

Как можноЯ убиваю командную задачу фонового работника с помощью кнопки остановки ... ??

Ответы [ 3 ]

2 голосов
/ 07 марта 2012

из MSDN

Метод Kill выполняется асинхронно. После вызова метода Kill вызовите метод WaitForExit, чтобы дождаться завершения процесса, или проверьте свойство HasExited, чтобы определить, завершился ли процесс.

Итак, это означает, что Kill также не сможет остановить процесс в течение некоторого периода времени.

Изменение вашего метода KillProcess, чтобы дождаться кода выхода и посмотреть, сколько времени потребуется, чтобы ответить. Возможно, вам придется предупредить пользователя о том, что вы ожидаете его завершения, пока вы ожидаете, пока Kill выполнит свою работу.

private void KillProcess(Process prc)
{
    if (prc != null)
    {
        prc.Kill(); 
        prc.WaitForExit(); //this has an [override][2] in which you can specify time
        MessageBox.Show("debug!");
    }
}
1 голос
/ 07 марта 2012

Вам нужно сохранить в памяти процесс, который вы смотрели. Сделайте что-то вроде этого:

private Process _commandProcess = null;

private void tsbStartRun_Click(object sender, EventArgs e)
{
    _commandProcess = new Process();
    //Start process here.
}

private void tsbStopRun_Click(object sender, EventArgs e)
{
    _commandProcess.Kill();
    MessageBox.Show("debug!");
}
0 голосов
/ 07 марта 2012

Я сделал нечто подобное для пользовательской службы сборки, которую я написал.Я создал свойство для отслеживания процесса.

public Process CurrentProcess { get; set; }

Затем, когда вы приступите к выполнению работы в фоновом рабочем потоке, вы можете инициализировать и запустить процесс.

this.CurrentProcess = new Process();
//other initialization
this.CurrentProcess.Start()

Тогда вы сможете получить доступ к свойству, чтобы убить процесс.В зависимости от того, как вы реализуете это, вы можете проверить, имеет ли свойство CurrentProcess значение NULL, или даже если фоновый работник работает, прежде чем пытаться завершить процесс.

this.CurrentProcess.Kill()
...