C # Process.Start () не удалось утилизировать ресурсы потока - PullRequest
1 голос
/ 19 декабря 2011

Код программы, как показано ниже:

using System.Diagnostics;

class Test
{
    static void Main()
    {
        using (Process p = Process.Start("notepad.exe"))
        {
        }
    }
}

Проблема в том, что когда эта программа была закрыта, а Блокнот все еще работает, Блокнот заблокирует его. И я не хочу закрывать Блокнот.
Я попытался использовать Unlocker для обнаружения проблемы.
Снимок экрана с результатом выглядит следующим образом:

Результат Image Link

Итак, я хочу запустить exe-файл и немедленно утилизировать все ресурсы потоков. Или я не могу удалить свою программу, пока все программы, открытые ею, не будут закрыты. Это может вызвать неприятный пользовательский опыт. Требование перезагрузки системы также неприятно. Unlocker может сделать это красиво. Если я использую Unlocker для разблокировки родительской папки, он не закроет Блокнот, и тогда я смогу удалить этот программный файл в обычном режиме.

Ответы [ 3 ]

1 голос
/ 19 декабря 2011

Проблема в том, что вы никогда не закрываете запущенный процесс, поэтому он продолжает выполняться, в результате чего Unlocker указывает, что он заблокирован.

Я вас знаю думаю вы сделали, потому что вы вызвали p.Close(), но хитрость в том, что метод Process.Close() делает не , заставляющим процесс закрыться.Он не отправляет сообщение WM_CLOSE или WM_QUIT в окно Блокнота.Все, что он делает - это освобождает ресурсы, связанные с процессом.

Вместо этого вам нужно использовать Process.CloseMainWindow() метод .Это отправит окну сообщение WM_CLOSE, в результате чего оно закроется должным образом.

Поэтому обновите свой код так, чтобы он выглядел следующим образом (как уже упоминалось, нет необходимости явно вызывать Dispose, если выуже обернуло создание объекта в оператор using):

using System.Diagnostics;

class Test
{
    static void Main()
    {
        using (Process p = Process.Start("notepad.exe"))
        {
            p.CloseMainWindow();
            p.Close();
        }
    }
}

Обратите внимание, что вы могли бы использовать Process.Kill() метод , но это похоже на поворотот компьютера, оторвав шнур питания от стены.Вместо того, чтобы просить приложение красиво закрыться, оно заставляет его завершиться, точно так же, как нажав «Завершить задачу» в диспетчере задач.Поэтому его следует использовать только тогда, когда процесс заблокирован или иным образом не отвечает на вежливые запросы на закрытие.


Кроме того, как упомянул Ролис в комментарии, приведенный выше код не будет оченьполезно.Вы просто запускаете Блокнот, а затем сразу закрываете его.

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

В этом случае вам нужно использовать метод Process.WaitForExit().Этот метод заблокирует вызывающий поток, ожидая, пока процесс завершится.Когда пользователь, наконец, закроет Блокнот, управление вернется к ветке вашего приложения, и вы сможете позвонить p.Close().

Например:

using System.Diagnostics;

class Test
{
    static void Main()
    {
        using (Process p = Process.Start("notepad.exe"))
        {
            p.WaitForExit();
            p.Close();
        }
    }
}
0 голосов
/ 19 декабря 2011

Здесь есть два возможных решения

  1. В вашем приложении дождитесь завершения процесса, прежде чем выходить из приложения. Есть несколько способов сделать это.
  2. Завершить процесс при выходе из приложения. Либо красиво или силой Последнее не очень красиво и может привести к потере данных, если пользователь что-то редактировал.

В случае №1 выше вы можете открыть диалоговое окно или что-то для пользователя, сообщающее, что вы ожидаете выхода из блокнота (возможно, с кнопкой, чтобы убить его)

0 голосов
/ 19 декабря 2011

Попробуйте просто запустить процесс, не обращаясь к нему:

Process.Start("notepad.exe");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...