如何创建自定义消息泵

如何创建自定义消息泵

本文介绍了如何创建自定义消息泵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做一个小的锻炼,我需要建立一个类似于一个消息泵。我已经是一个工作队列做的,我想工作,完全在一个线程来完成,而任何线程可以增加工作队列工作要做。

I am doing a small exercise where I need to create something akin to a message pump. What I have is a queue of work to do, and I want the work to be done entirely on one thread while any thread can add work to the queue to be done.

Queue<WorkToDo> queue;



该线程使用等待句柄来告诉泵,有工作要做。

The threads use a wait handle to tell the pump that there is work to do.

WaitHandle signal;



泵只是循环只要有工作要做,然后等待信号再次开始

The pump just loops as long as there is work to do and then waits for the signal to start again.

while(ApplicationIsRunning){
    while(queue.HasWork){
        DoWork(queue.NextWorkItem)
    }
    signal.Reset();
    signal.WaitOne();
}



每其他线程可以增加工作队列和信号等待句柄..

Every other thread can add work to the queue and signal the wait handle...

public void AddWork(WorkToDo work){
    queue.Add(work);
    signal.Set();
}



现在的问题是,如果被添加足够快的工作,可能会出现一个条件在那里工作可以在队列中离开,因为工作队列检查和对WaitHandle的复位之间,另一个线程可以增加工作队列中。

The problem is, if work is being added fast enough, a condition can occur where work can be left in the queue because the between the queue check for work and the the WaitHandle reset, another thread can add work to the queue.

我将如何去?关于减轻那种情况下没有把周围的WaitHandle的一个昂贵的互斥

How would I go about mitigating that circumstance without putting a costly mutex around the the WaitHandle?

推荐答案

您可以使用 BlockingCollection< T> 来使执行队列中的的容易,因为它会为您处理同步:

You can use BlockingCollection<T> to make implementing the queue much easier, as it will handle the synchronization for you:

public class MessagePump
{
    private BlockingCollection<Action> actions = new BlockingCollection<Action>();

    public void Run() //you may want to restrict this so that only one caller from one thread is running messages
    {
        foreach (var action in actions.GetConsumingEnumerable())
            action();
    }

    public void AddWork(Action action)
    {
        actions.Add(action);
    }

    public void Stop()
    {
        actions.CompleteAdding();
    }
}

这篇关于如何创建自定义消息泵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 22:47