Suspend a thread while waiting for events
I am trying to use a separate thread to handle specific events in VB.Net. The idea being that I do not want the main application to be held up if a particular event handler takes awhile to finish. How do I get my main thread loop to suspend the thread while allowing it to handle events when they occur?
When I create a Windows Forms application, there is a UI thread that handles the UI events. I do not imagine that this thread is continuously polling some variable to see if someone has pressed a button. I imagine the thread is suspended until the OS tells it there is something to do. I was trying to figure out how to ensure that my event handlers were not being executed by the UI thread. From what I have read, I can do this by raising the events from a different thread. But what does that thread do while it is waiting for other events, just exit?
I wanted to know how to create a thread that works like the UI thread, only it processes the events I want it to process. I am not sure how events work in .Net. I understand 开发者_JAVA技巧that event handlers are run on the thread that raises the event. I believe that .Net allocates threads from some thread pool to process events such as timer events. I am not clear on how it works, though, and what those threads are doing when they are not handling events.
Based on your comments I can see that what you want can best be solved by using the producer-consumer pattern. With this pattern the consumer thread is constructed and started in such a manner that it spins around a loop indefinitely waiting for items to appear in a queue. A UI thread will use this same pattern to implement its message loop. Here is how it works.
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);
}
}
The magic happens in the Take
method. This method is designed to "suspend" (your terminology, not mine) or change the state of the thread to WaitSleepJoin
while the queue is empty. Once an item is queued the consuming thread wakes up and the Take
method returns the next item. That is the general pattern used in the message loop of a UI thread except instead of queueing plain old object
instances Windows is posting System.Windows.Forms.Message
values. You could do something similar by posting Delegate
instances that would then be processed on the consumer thread once they arrive.
You can have the current thread sleep for a specified amount of milliseconds:
Threading.Thread.Sleep(100)
This will sleep for 1/10sec.
However if you need queued events to happen on the current thread, you can use:
Application.DoEvents()
The primary issue with using DoEvents is you don't know how much work actually gets done so it can be somewhat unreliable depending on what you are trying to accomplish.
精彩评论