2010-03-27 2 views
7

Не могли бы вы рассказать мне, как мне приостановить мою программу на 500 миллисекунд, а затем продолжить?C# Сон за 500 миллисекунд

Я читал Thread.Sleep(500) не очень хорошо, поскольку он держит резьбу GUI.

Использование таймера Стреляет обратного вызова ...

Я просто хочу, чтобы ждать 500мс, а затем переходите к следующему утверждению.

Просьба сообщить.

EDIT: Мне нужно отобразить сообщение в строке состояния на 500 мс, а затем обновить сообщение другим. Извините, я имел в виду 500 не 50.

EDIT: Я понимаю, что вы сказали. но: [Я просто хочу подождать 500 мс, а затем перейти к следующему утверждению.] Я думаю, потому что это такой короткий промежуток, который я собираюсь сделать Thread.Sleep (500) в основном потоке графического интерфейса. В противном случае мне пришлось бы переписать много кода, чтобы разместить этот короткий интервал в 500 миллисекунд.

EDIT: я попытаюсь переформатировать мое сообщение о статусе, чтобы пауза не нужна.

ответ

5

Хмья, что вы пытаетесь сделать, принципиально несовместимо с моделью программирования Windows. Собственная программа Windows управляется событиями. Ваша программа всегда бездействует, сидя внутри цикла, запущенного Application.Run(), ожидая, пока Windows сообщит, что произошло что-то интересное, на которое он должен ответить. Запросы на краску, щелчки мыши, выдержки по таймеру, такие вещи.

Ваша программа должна ответить на это и фильтровать то, что вам интересно. Когда вы бросаете кнопку в форме, вы всегда заинтересованы в событии Click, сгенерированном, когда Windows отправляет уведомление MouseDown. Обработчик событий Click запускает какой-то пользовательский код, который вы пишете. Как и обновление сообщения строки состояния в вашем случае.

Обновление сообщения о статусе через полсекунды позже не делает целого heckofalot смысла. Что именно произошло за эти 500 миллисекунд, которые изменили способ реагирования вашей программы на события? Вы можете вызвать метод Update() для StatusBar, чтобы новое сообщение было видимым, а затем вызовите System.Threading.Thread.Sleep (500), чтобы получить то, что вы хотите. Вы уйдете с ним, «Не реагирующий» призрак, который запускает Windows, заставляет вашу программу месть в течение нескольких секунд.

Но это не имеет большого смысла, ничего не происходило за эту половину секунды, состояние вашей программы не изменилось. Он не мог измениться, он был мертв для Windows и не получал никаких сообщений, которые позволяли бы ему изменять состояние.

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

+0

Я пытаюсь представить информацию о состоянии приложения пользователю в кусках. У меня есть полная информация, но я думаю, было бы лучше, если бы она была представлена ​​в два шага вместо этого на целую кучу информации сразу. [Ваши комментарии были полезны, спасибо]. – iTEgg

+0

@ikurtz: Означает ли это, что вы хотите сообщить своему пользователю о важных шагах, которые вы предприняли в своем коде? Это заняло всего несколько миллисекунд, слишком быстро для пользователя? Нет, она не заинтересована, она заботится о результате. Вы уже сделали «Правильную вещь», вы убедились, что это действительно сделано быстро. Хорошая работа, ваши коллеги-программисты оценят это. Не ваш пользователь. Ну, так она и думает. –

+0

Спасибо. Снова мне понравился ваш ответ, поскольку он заставил меня пересмотреть мои действия и цели. Время от времени лучше предлагать мысли, чем кодовые решения. – iTEgg

4

Вместо того, чтобы приостанавливать интерфейс пользователя в течение 500 мс, вы всегда можете использовать BackgroundWorker. Это заставит ваш callback работать в отдельном потоке, где вы можете использовать Thread.Sleep, чтобы приостановить его, не блокируя пользовательский интерфейс. Затем, когда вы закончите, просто обновите строку состояния своим новым сообщением.

2

Дополнительный контекст к вопросу был бы полезен.

Thread.Sleep(50) приостановит текущий поток на 50 миллисекунд. Если вы делаете это в потоке пользовательского интерфейса, то да, он заморозит пользовательский интерфейс на 50 миллисекунд. Однако, если вы используете другой поток для этой обработки, вызов Sleep в этом потоке приостанавливает его на 50 миллисекунд без замораживания вашего потока пользовательского интерфейса.

См. Ответ Марка на вопрос this на примере использования экземпляра BackgroundWorker, чтобы сделать то, что вам нужно.

5

У вас есть два варианта:

  • Используйте таймер, как вы предложили. Разделите свой метод на два метода: foo1 и foo2. Используйте foo1, чтобы запустить таймер и запустить foo2 в обратном вызове.
  • Используйте функцию BackgroundWorker для запуска всей функции и используйте Thread.Sleep в рабочей ветке.

Из вашего обновления кажется, что единственное, что вы хотите сделать, это изменить одно поле. Я бы определенно рекомендовал первый метод: использование таймера. Запуск BackgroundWorker для этой задачи является излишним и просто даст вам лишнюю дополнительную работу и осложнения.

+0

Дело в том, что я не хочу обратного вызова. я просто хочу продолжить следующую строку после паузы. – iTEgg

+0

@ikurtz: Почему вы не хотите обратного вызова? Вы можете поместить свой обратный вызов в свою первую функцию, если ваша причина избежать обратных вызовов заключается в том, что вы хотите сохранить все вместе. Но мне кажется, что единственный ответ, который вам понравится, - это если кто-то скажет вам использовать 'Application.DoEvents()'. Это, вероятно, будет работать, но это не лучший способ сделать это. –

0

Вам необходимо выделить другой поток. В этой теме вы получите Sleep(500) и измените необходимые данные. Внимание: вам нужно будет использовать диспетчер исходного потока, потому что данные, относящиеся к пользовательскому интерфейсу, обычно должны обновляться из потока графического интерфейса.

2

В C# ваш лучший выбор - использовать таймер и запустить обратный вызов.

В F # есть удивительный способ сделать то, что вы хотите, видеть

F# async on the client side

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

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