Click here to Skip to main content
15,616,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Originally I used queue to solve my problem. The application is a concurrent calls. Each time it only can take 4 calls.(MaximumChannels)
C#
public static int m_ActiveCallCount = 0;
public static int MaximumChannels = 4;
public static object m_SyncVar = new object();
public static Queue<AppointmentReminder> m_Queue = new Queue<AppointmentReminder>();

public static void IncrementCallCounters()
{
    Interlocked.Increment(ref m_ActiveCallCount);
}

After adding tons of items to the queue, I had the code to run.
C#
while (true)
                {
                    AppointmentReminder reminder = null;
                    if (m_ActiveCallCount < MaximumChannels)
                    {
                        lock (m_SyncVar)
                        {
                            // Make sure we have values to read
                            if (m_Queue.Count > 0)
                            {
                                reminder = m_Queue.Dequeue();
                            }
                        }
                        if (reminder != null)
                        {
                            Dial dial = new Dial(tServer);
                            Thread oThread = new Thread(() => dial.RunScript(reminder));
                            IncrementCallCounters();
                            oThread.Start();
                        }
                    }

Now I want to use BlockingCollection http://msdn.microsoft.com/en-us/library/dd267312(v=vs.110).aspx[^] to replace queue. The problem I have is that I am not sure how to apply the boundary number herein referring to "MaximumChannels" with BlockingCollection class.

I need the code hint.
Thanks.
Posted
Updated 24-Sep-14 4:46am
v3
Comments
Sergey Alexandrovich Kryukov 24-Sep-14 11:03am    
Not clear what do you mean by "replacing a queue". And what's the idea of that "replacement". Why?

I do understand that the problem of over-populating of the queue is the problem. This is a general problem of the producer-consumer pattern. It is addressed in "bounding" if the collection described in its documentation.

—SA
[no name] 24-Sep-14 11:54am    
Replacement means: I want to use
public static BlockingCollection m_Queue = new BlockingCollection(); to replace queue class. Because it is thread-safe.

The question is if I apply the boundary to the collection.
public static BlockingCollection m_Queue = new BlockingCollection(MaximumChannels);

It only processes MaximumChannels items.

I heard about ActionBlock Class etc.
Sergey Alexandrovich Kryukov 24-Sep-14 11:59am    
Right. This is what I mentioned in my answer. Before we can continue this discussion, please read it and then reply. Why bounding (by maximum number) is not good enough for you?
—SA
[no name] 24-Sep-14 13:52pm    
Because right now I just test the project, I haven't used the while loop in producer method. If I add an upper boundary, the producer only has 4 items. If I don't use the boundary, I have to retrieve 4 items in the consumer method each time. The difficult thing to me is I how to apply the constraint in the consumer. I don't know how to do it.

Do I need still use IncrementCallCounters(); and so on?
Or use something like BufferBlock such as http://blog.stephencleary.com/2012/11/async-producerconsumer-queue-using.html
Sergey Alexandrovich Kryukov 24-Sep-14 15:19pm    
I don't really understand why would you use the while loop in producer method. It is not assumed in the pattern. Generally, the pattern assumes that you "infinitely" adds items as they are created, typically, until the end of the lifetime of the application. And the consumer works in an "infinite" loop retrieving items as they become available in the queue. Hence the blocking character of this code: the consumer is put to a wait state (spending zero CPU time) if it requested for another item when it collection is empty. If you are doing something else, you may need to review the design.

The issue is the behavior of the producer when the collection is full. Usually, it needs to be put to wait state, too. What would you need? This is not clear.

Why 4 items? What's wrong with 4 items? If 4 always come together, it would also mean a different pattern. Doesn't it mean that you need to have only one item of different type, composing the 4? I don't know. I would really need to know your whole problem.

—SA

1 solution

Please see my comment to the question. Even though it is not 100% clear to me, but this looks like a general problem of the producer-consumer pattern: [Sorry, we are experiencing the problem of broken anchors in CodeProject posts; please use:
http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem;
sorry for the inconvenience].

The class BlockingCollection<T> offers bounding (not to be confused with the notion of binding):
MSDN tells us:
BlockingCollection<t> is a thread-safe collection class that provides the following:
[…]
A bounded collection that blocks Add and Take operations when the collection is full or empty.
Please pay attention for these constructors defining bounding:
http://msdn.microsoft.com/en-us/library/dd267301(v=vs.110).aspx[^],
http://msdn.microsoft.com/en-us/library/dd267306(v=vs.110).aspx[^]
and for this member: http://msdn.microsoft.com/en-us/library/dd287159(v=vs.110).aspx[^].

See also: How to: Add Bounding and Blocking Functionality to a Collection.

As to the "replacing" (why?), consider adding and the methods named Skip*.

—SA
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900