8

I have a list of work items that need to be processed in order. Sometimes the list will be empty, sometimes it will have a thousand items. Only one can be processed at a time and in order. Currently I am doing the following which to me looks stupid because i am using Thread.Sleep in the consumer task to wait for 100ms before checking if the list is empty or not. Is this the standard way to do it or am I completely wrong.

public class WorkItem
{

}

public class WorkerClass
{
    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken ct = new CancellationToken();

    List<WorkItem> listOfWorkItems = new List<WorkItem>();

    public void start()
    {
        Task producerTask = new Task(() => producerMethod(ct), ct);
        Task consumerTask = new Task(() => consumerMethod(ct), ct);

        producerTask.Start();
        consumerTask.Start();
    }

    public void producerMethod(CancellationToken _ct)
    {

        while (!_ct.IsCancellationRequested)
        {
            //Sleep random amount of time
            Random r = new Random();
            Thread.Sleep(r.Next(100, 1000));

            WorkItem w = new WorkItem();
            listOfWorkItems.Add(w);
        }
    }

    public void consumerMethod(CancellationToken _ct)
    {

        while (!_ct.IsCancellationRequested)
        {
            if (listOfWorkItems.Count == 0)
            {
                //Sleep small small amount of time to avoid continuously polling this if statement
                Thread.Sleep(100);
                continue;
            }

            //Process first item
            doWorkOnWorkItem(listOfWorkItems[0]);

            //Remove from list
            listOfWorkItems.RemoveAt(0);
        }
    }

    public void doWorkOnWorkItem(WorkItem w)
    {
        // Do work here - synchronous to execute in order (10ms to 5min execution time)
    }

}

Advise greatly appreciated.

Thanks

Peter
  • 1,685
  • 3
  • 16
  • 22

2 Answers2

8

Use BlockingCollection. It does non-busy waits.

See https://stackoverflow.com/a/5108487/56778 for a simple example. Or http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=821 for a bit more detail.

Community
  • 1
  • 1
Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
3

You can use the BlockingCollection<T> Class.

dtb
  • 213,145
  • 36
  • 401
  • 431