Click here to Skip to main content
15,891,248 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have an application with producer-consumer pattern. Because I am not strong on TPL, so I made a simple test class to do it.

Basically in the producer method, I added 100 number to the queue then print them in consumer. The code is straightforward.
C#
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;

namespace ConcurrentScheduler
{
    class Program
    {
        public static BufferBlock<int> m_Queue = new BufferBlock<int>();


        static void Main(string[] args)
        {
            Task first = Task.Factory.StartNew(() => Console.WriteLine("Begin"));
            var t = first.ContinueWith((a) => Producer()); // producer task
            var c = t.ContinueWith((w) => Consumer());
            first.Wait();
        }

        private static void Producer()
        {
            for (int i = 0; i < 100; i++)
            {
                m_Queue.SendAsync(i);
            }
            m_Queue.Complete();
            Console.WriteLine("There are {0} items in the queue.\n", m_Queue.Count);
        }

        private static void Consumer()
        {
            try
            {
                var consumerBlock = new ActionBlock<int>(
                   data => RunScript(data),
                   new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });
                m_Queue.LinkTo(
consumerBlock, new DataflowLinkOptions { PropagateCompletion = true });

                consumerBlock.Completion.Wait();
            }
            catch (NullReferenceException ex)
            {
                Console.WriteLine("NullReferenceException: " + ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public static void RunScript(int number)
        {
            try
            {
                Thread.Sleep(500);
                Console.WriteLine(number);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
    }

My question, it never reached the consumer part. No print at all.
Posted
Comments
CHill60 3-Oct-14 14:17pm    
That's not a question, it's a statement. Try debugging it. Bear in mind that the window will close when the program finishes so you probably won't see the output anyway
[no name] 3-Oct-14 14:43pm    
No, I set the breakpoint at RunScript(), it never be hit. If you doubt the window will close too quick, we can add more items to the queue. Let's say add 1000000 numbers to the queue, but still nothing.
CHill60 3-Oct-14 21:29pm    
Try stepping through the code one line at atime

Hi,

Spending more time in the consumer will not bring you to a solution.

The problem is that you tell the queue to Complete before all Consumers are ready.
The call to m_Queue.Complete() signals to the IDataflowBlock that it should not accept nor produce any more messages nor consume any more postponed messages.

See http://msdn.microsoft.com/en-us/library/hh160414(v=vs.110).aspx[^]

Piet
 
Share this answer
 
Comments
[no name] 4-Oct-14 14:02pm    
I commented out m_Queue.Complete() but it is still not working. Would you please test it in your side?
The problem is that your app is exiting before it gets a chance to run. You're waiting on the first task to complete so as soon as that occurs (which is near instant) then the app exits. If you change the logic to wait for the last task to complete (c) then you'll block until all the work is done.

At this point though your Consumer method runs but when it hits the Wait method it'll block forever.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 26-Feb-15 11:14am    
Who are you talking to? To yourself? Aren't you a cheater?
—SA
[no name] 26-Feb-15 11:21am    
I don't understand your point. I am not a cheater, I got the answer from another web site and just copied and pasted the context without modification(just forgot it). Please speak politely. It is a public forum.
Sergey Alexandrovich Kryukov 26-Feb-15 11:23am    
What is unclear in my point? Please see my last comment.
—SA

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