2015-03-31 7 views
0

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

for (int i = 0; i < 20; i++) 
{ 
    Process pro = new Process(); 
    pro.StartInfo.FileName = @"C:\Program Files (x86)\Mozilla Firefox\firefox.exe"; 
    pro.StartInfo.WindowStyle = ProcessWindowStyle.Minimized; 
    pro.Start(); 

    Thread.Sleep(8000); 

    try 
    { 
     pro.Kill(); 
     Thread.Sleep(1000); 
    } 
    catch 
    { 
     return; 
    } 
} 

Как я запустить приложение либо в режиме отладки или непосредственно из EXE-файла, он успешно запускается и убивает процесс, но он заморожен. Я не могу переместить его окно или щелкнуть по другим кнопкам.

+5

Это потому, что формы Win однопоточные, а замкнутая петля без выхода не оставляет места для системы, чтобы перекрасить вашу форму или ответить на события мыши. – Jeremy

+0

Любые решения, чтобы убежать от этого? – Dionisis

+0

не делайте этого .... – Jeremy

ответ

1

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

Очевидное решение будет делать это в новой ветке.

Как Servy sais, это не отличная идея. Вы можете использовать таймер (https://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx) для ожидания вместо блокировки потока пользовательского интерфейса.

+2

Создание нового потока только для того, чтобы он мог сидеть и ничего не делать ~ 100% времени - ужасная идея. – Servy

+0

@Servy Что вы предлагаете? – Dionisis

+0

Выполняйте работу асинхронно. Это настольный UI 101. – Servy

12

заморожен. Я не могу переместить его окно или нажать другие кнопки.

Это правильно. Ты сказал, чтобы спать нить.

Люди, похоже, имеют эту странную идею о том, что запуск кода при нажатии кнопок происходит по волшебству. Это не происходит по волшебству. Это происходит потому, что поток выполняет код, который обрабатывает сообщение «a button click» от операционной системы. Если вы помещаете поток в режим ожидания, он перестает обрабатывать эти сообщения, потому что он спит.

Ввод нить в сон в 99% случаев совершенно неправильной вещи, поэтому просто не делайте этого.

Правильная вещь, чтобы сделать в C# 5, - это сделать свой метод async, а затем сделать await Task.Delay(whatever). В качестве альтернативы, создайте таймер, который тикает через некоторое количество секунд. В событии обработки тика выключите таймер и выполните свою логику.

+1

У меня есть приложение .NET, которое работает в фоновом режиме, которое должно выполнять свои действия самым легким способом, с минимальным воздействием на систему. Я перебирал ресурсоемкие вызовы с помощью вызовов «Thread.Sleep (1)». Считаете ли вы, что это приемлемо, или есть лучший способ контролировать использование ресурсов в .NET? –

+4

@LucaCremonesi: Это совсем не так, как я бы это сделал, и я понятия не имею, почему вы думаете, что это поможет вам достичь своей цели. Каковы ваши точные, измеримые цели и какие эмпирические данные вы собрали, что этот метод достигает ваших целей? Какую пользу вы считаете, что «Сон (1)» закончился, скажем «Урожай»? –

+2

Или, что не так, просто устанавливая класс приоритета потока ниже среднего, если вы хотите, чтобы все другие не-холостые потоки имели приоритет? –

0

Основная тема вашего приложения - это цикл, который постоянно просматривает сообщения из очереди сообщений Windows. Это похоже на совместную многопоточность - если вы не обновляете свой пользовательский интерфейс явно, это не будет делать это автоматически. И это не потому, что ваша программа (основной поток) просто порождает процесс, а затем спит, а затем убивает его (вам даже не нужно, чтобы try/catch block - любое исключение в любом потоке вашего приложения завершает его). Спящий в потоке блокирует его. И поскольку вы спите в главном потоке (UI), вы блокируете приложение от подсмотра из очереди сообщений.

Смежные вопросы