为什么消费者按顺序而不是同时运行? [英] Why the consumer running sequentially rather than concurrently?

查看:103
本文介绍了为什么消费者按顺序而不是同时运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个生产者和四个消费者。我想要四个消费者同时处理来自生产者的物品。但事实并非如此。它是顺序的。

我把所有代码放在这里。感谢您的帮助。

I have one producer and four consumers. I want four consumers process items from the producer concurrently. However, it is not. It is sequentially instead.
I put all code here. Thanks for help.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConcurrentMakeTest
{
    class Program
    {
        public static BlockingCollection<string> m_Queue =
             new BlockingCollection<string>();
        public static Object obj = new Object();
        static void Main(string[] args)
        {
            Task producer = Task.Run(() => Producer());
            Task consumer1 = Consumer();
            Task consumer2 = Consumer();
            Task consumer3 = Consumer();
            Task consumer4 = Consumer();

            Task.WaitAll(producer, consumer1, consumer2, consumer3, consumer4);
            Console.WriteLine("-----------------------------------------");
            Console.ReadLine();
        }
        static void Producer()
        {
            try
            {
                for (int i = 0; i <= 10; i++)
                {
                    m_Queue.TryAdd(i.ToString());
                }
            }
            finally
            {
                m_Queue.CompleteAdding();
                Console.WriteLine("There are totally {0} items in the queue.\n", m_Queue.Count);
                Thread.Sleep(500);
            }
        }
        static async Task Consumer()
        {
            try
            {
                while (m_Queue.Count > 0)
                {
                    string x = "";
                    m_Queue.TryTake(out x);
                    await Task.Factory.StartNew(() =>
                    {
                        lock (obj)
                        {
                            PrintItem m = new PrintItem(DateTime.Now);
                            m.RunScript(x);
                        }
                    });
                }

            }
            catch (Exception ex)
            {
                Console.Write("Exception: " + ex.Message + "\r\n" + ex.StackTrace);
            }
        }
    }
}



和:


And:

public class PrintItem
    {
        public PrintItem(DateTime t)
        {
            Console.WriteLine(t);
        }
        internal void RunScript(string item) 
        {
            Console.WriteLine(item);
        }
    }

推荐答案

因为在大多数情况下,他们在等待对方在同一个锁对象的锁上排队, obj 。代码并没有设计得过于充分利用并行性。看看 RunScript(x)是什么?对这种方法的不同调用是否真的需要互锁并一次调用一个?为什么?如果它们不必互锁,请取下锁。小心。



还有什么建议?考虑重新设计代码。怎么样?也许,如果我知道这一切,我可以建议一些设计:你的范围,目标等。



一个想法是:也许你需要学习线程,线程同步,任务(TPL)和并行性首先解决一些更简单的问题。即使您完全理解代码的行为,合理有效的设计也不是微不足道的。我不能肯定地说;也许你现在的问题足够合理,可以全部学习。



-SA
Because, most of the time, you they are waiting for each other at the queue at the lock on the same lock object, obj. The code is just not designed too leverage parallelism well enough. Look at what RunScript(x) does? Do the different calls to this method really need to be interlocked and called one at a time? Why? If they don't have to be interlocked, remove the lock. Be careful.

What else to advise? Consider redesign of the code. How? Probably, I would be able to advise some design if I knew it all: your scope, goals, etc.

One idea is: maybe you need to learn threading, thread synchronization, tasks (TPL) and parallelism on some simpler problems first. Even when you perfectly understand the behavior of code, reasonable efficient design is not trivial at all. I cannot say for sure though; maybe your present problem is reasonable enough to learn it all.

—SA


这篇关于为什么消费者按顺序而不是同时运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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