views:

59

answers:

2

I'm trying to improve performance of an application by introducing threading (see my earlier question). I have filled a Queue(of String) with XML messages and I now want to setup two threads to post these messages to a webserver). This process needs to ensure that each message is only posted once. Would a BackgroundWorker (or two) be suitable for this?

I'm not sure where to start with this, some of the samples I've looked at don't make much sense! Any help gratefully recieved.

+2  A: 
using System;
using System.Collections.Generic;
using System.Threading;

namespace QueueTest
{
    class QueueTest 
    {
        [STAThread]
        static void Main(string[] args)
        {
            QueueTest d = new QueueTest();
            d.Run();
        }

        Queue<string> m_Queue=new Queue<string>();

        QueueTest()
        {
            for (int i = 0; i < 10000; i++)
            {
                m_Queue.Enqueue("Message " + i);
            }
        }

        private void Run()
        {
            //Create and start threads
            Thread t1 = new Thread(new ThreadStart(QueueReader));
            Thread t2 = new Thread(new ThreadStart(QueueReader));
            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();
        }

        //Thread function
        private void QueueReader()
        {
            while (true)
            {
                string msg = null;
                lock (m_Queue)
                {
                    if (m_Queue.Count > 0)
                        msg = m_Queue.Dequeue();
                    else
                    {
                        return;
                        //whatever you want to do when a queue is empty, for instance
                        //sleep or exit or wait for event. 
                        //but you have to do something here to avoid empty loop with 100% CPU load
                        Thread.Sleep(1000);
                    }
                }
                //this is where you post your message 
                //it's important to do this outside lock()
                if (msg != null) ProcessMessage(msg);
            }
        }

        private void ProcessMessage(string msg)
        {
            Console.WriteLine(msg);
            Thread.Sleep(500);
        }
    }
}
yu_sha
Thanks for replying. This never seems to get to the Dequeue statement. The Queue.Count shows correctly but it seems to give up at this point, I can't access any of the messages.
Simon
I edited the message and posted the full class in C#. It's tested and works. Equivalent in VB.Net should work too (use SyncLock ....End SyncLock statement)
yu_sha
It was the Join statements that seemed to cause this. I've accepted your answer, cheers!
Simon
Join tells the main thread to wait for your threads to finish. So, while there are messages Join will "hang"
yu_sha
A: 

Also you can use ConcurrentQueue<T> from http://blogs.msdn.com/pfxteam/ library called Parallel Extensions Framework.

Vasiliy Borovyak