在等待事件时挂起一个线程

时间:2011-07-01 15:36:13

标签: vb.net multithreading event-handling

我正在尝试使用单独的线程来处理VB.Net中的特定事件。我的想法是,如果特定事件处理程序需要一段时间才能完成,我不希望主应用程序被阻止。如何让我的主线程循环暂停线程,同时允许它在事件发生时处理事件?

当我创建Windows窗体应用程序时,有一个UI线程来处理UI事件。我不认为这个线程会不断轮询某个变量,看是否有人按下了按钮。我想这个线程是暂停的,直到操作系统告诉它有事情要做。我试图弄清楚如何确保我的事件处理程序没有被UI线程执行。根据我的阅读,我可以通过从不同的线程中提升事件来做到这一点。但是,当它等待其他事件时,该线程做了什么,只是退出?

我想知道如何创建一个像UI线程一样工作的线程,只是它处理我希望它处理的事件。我不确定.Net中的事件是如何运作的。我知道事件处理程序是在引发事件的线程上运行的。我相信.Net从某个线程池分配线程来处理事件,如计时器事件。我不清楚它是如何工作的,以及那些线程在不处理事件时正在做什么。

2 个答案:

答案 0 :(得分:1)

根据你的评论,我可以看到你想要的东西最好通过使用生产者 - 消费者模式来解决。使用此模式,构造和启动使用者线程,使其围绕循环旋转,无限期地等待项目出现在队列中。 UI线程将使用相同的模式来实现其消息循环。这是它的工作原理。

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方法会返回下一个项目。这是UI线程的消息循环中使用的一般模式,除了不是排队普通的旧object实例,Windows发布System.Windows.Forms.Message值。你可以通过发布Delegate个实例来做类似的事情,这些实例一旦到达就会在消费者线程上处理。

答案 1 :(得分:0)

您可以使当前线程休眠指定的毫秒数:

Threading.Thread.Sleep(100)

这将睡眠1/10秒。

但是,如果您需要在当前线程上发生排队事件,则可以使用:

        Application.DoEvents()

使用DoEvents的主要问题是您不知道实际完成了多少工作,因此根据您要完成的工作,它可能有些不可靠。