简体   繁体   中英

Queueing Operation

im sending smses using dll, that dll have some events one them is

Session_OnMessageAccepted

inside that im doing something like this

   void Session_OnMessageAccepted(object sender,EventArgs e)
     {
         new Thread(
             delegate()
                 {
                     //do stuff
                 }).Start();
     }

this is ok only problem is the code inside dostuff gets excuted same time , is there is any chance i can put "dostuff"in a queue and make it happen synchronously?

您正在寻找ConcurrentQueue

You can add the messages in the queue. And you can have a separate thread started(On App Start) which will continuously look for messages in the queue and process it.

ie in the thread method

while(true)
{
    //check if the queue is empty otherwise continue;
    //fetch the element
    //process it
}

A Note About The ThreadPool

As a general comment to your current code, consider using ThreadPool.QueueUserWorkItem rather than creating new threads.

Queuing work items to the ThreadPool is much more efficient than creating new threads for short term tasks. The ThreadPool maintains a pool of existing threads and re-uses them. Creating and managing threads is expensive so should be avoided when needing many short-lived tasks. As well as being efficient, the ThreadPool also has natural queuing behaviour.

However, using the ThreadPool does not guarantee that items are executed in the order you queued them, and may also result in items being executated at the same time ie concurrently. Therefore the ThreadPool doesn't help you out for this particular quesiton.

Example Message Processing Loop

The following is a message processing loop pattern which allows operations to be queued and then processing on a separate thread serially.

public class SomeClass
{
    private readonly object _syncObj = new object();
    private readonly Thread _thread;
    private readonly Queue<Action> _queue = new Queue<Action>();
    private readonly ManualResetEvent _messageAccepted = new ManualResetEvent(false);

    public SomeClass()
    {
        _thread = new Thread(() =>
        {
            while (true)
            {
                Action operation;

                while (TryDequeue(out operation))
                {
                    operation();
                }

                _messageAccepted.WaitOne();
            }
        }) {IsBackground = true};

        _thread.Start();
    }

    private void Session_OnMessageAccepted(object sender, EventArgs e)
    {
        Action operation = () =>{/* Do stuff */};

        Enqueue(operation);
    }

    private void Enqueue(Action operation)
    {
        lock (_syncObj)
        {
            _queue.Enqueue(operation);

            _messageAccepted.Set();
        }
    }

    private bool TryDequeue(out Action operation)
    {
        lock (_syncObj)
        {
            operation = (_queue.Count != 0) ? _queue.Dequeue() : null;

            if (operation == null) _messageAccepted.Reset();

            return (operation != null);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM