消费者不工作。 [英] Consumer is not working.

查看:117
本文介绍了消费者不工作。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个生产者 - 消费者模式的应用程序。因为我对TPL并不强,所以我做了一个简单的测试类来做它。



基本上在生产者方法中,我在队列中添加了100个数字然后打印他们是消费者。代码很简单。

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.

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.

推荐答案





在消费者身上花更多时间不会带给你解决方案。



问题是你在所有消费者准备好之前告诉队列完成。

调用m_Queue.Complete()信号给IDataflowBlock,它不应该接受也不会产生任何更多的消息,也不会消耗更多的推迟消息。



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



Piet
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


问题是你的应用程序在有机会运行之前就已退出。你正在等待第一个任务完成,所以一旦发生(即将到来),应用就会退出。如果您更改逻辑以等待上一个任务完成(c),那么您将阻止所有工作完成。



此时虽然您的消费者方法运行但是当它遇到Wait方法时它会永远阻塞。
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.


这篇关于消费者不工作。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆