Приостановить поток во время ожидания событий - PullRequest
0 голосов
/ 01 июля 2011

Я пытаюсь использовать отдельный поток для обработки определенных событий в VB.Net. Идея в том, что я не хочу, чтобы основное приложение задерживалось, если конкретный обработчик событий занимает некоторое время, чтобы закончить. Как заставить мой основной цикл потока приостановить поток, позволяя ему обрабатывать события, когда они происходят?

Когда я создаю приложение Windows Forms, существует поток пользовательского интерфейса, который обрабатывает события пользовательского интерфейса. Я не представляю, что этот поток постоянно опрашивает некоторую переменную, чтобы увидеть, нажал ли кто-то кнопку. Я предполагаю, что поток приостановлен, пока ОС не скажет, что есть что-то делать. Я пытался выяснить, как убедиться, что мои обработчики событий не выполняются потоком пользовательского интерфейса. Из того, что я прочитал, я могу сделать это, подняв события из другого потока. Но что этот поток делает, ожидая других событий, просто завершается?

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

Ответы [ 2 ]

1 голос
/ 14 июля 2011

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

public class DedicatedProcessingThread
{
  private BlockingCollection<object> m_Queue = new BlockingCollection<object>();

  public Consumer()
  {
    new Thread(
      () =>
      {
        while (true)
        {
          object item = m_Queue.Take(); // This blocks until an item appears.
          // Do something with item here.
        }
      }).Start();
  }

  public void Post(object item)
  {
    m_Queue.Add(item);
  }
}

Волшебство происходит в методе Take. Этот метод предназначен для «приостановки» (ваша терминология, а не моя) или изменения состояния потока на WaitSleepJoin, когда очередь пуста. Как только элемент помещается в очередь, поток-потребитель просыпается, и метод Take возвращает следующий элемент. Это общий шаблон, используемый в цикле сообщений потока пользовательского интерфейса, за исключением того, что вместо очередей старых object экземпляров Windows публикует System.Windows.Forms.Message значения. Вы можете сделать нечто подобное, разместив Delegate экземпляров, которые затем будут обработаны в потоке-получателе после их поступления.

0 голосов
/ 01 июля 2011

Текущий спящий поток может быть задан в течение указанного количества миллисекунд:

Threading.Thread.Sleep(100)

Это будет неактивно в течение 1 / 10сек.

Однако, если вам нужно, чтобы события с очередями происходили в текущем потоке, вы можете использовать:

        Application.DoEvents()

Основная проблема с использованием DoEvents заключается в том, что вы не знаете, сколько работы фактически выполняетсятак что это может быть несколько ненадежно в зависимости от того, чего вы пытаетесь достичь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...