首页 \ 问答 \ 简单的生产者 - 消费者示例C#Dictionary(Simple producer-consumer example C# Dictionary)

简单的生产者 - 消费者示例C#Dictionary(Simple producer-consumer example C# Dictionary)

我在并行编程中迈出了第一步。 我写了一个最简单的代码,但结果很混乱。 此代码使用生产者 - 消费者模式获取前10个最近的项目。 只有1个消费者和1个生产者。 两个消费者的工作做得更好,但也不正确。

  public static void ProducerConsumer(string path)
    {
        var capacity = 50000;
        var collection = new BlockingCollection<string>(capacity);
        var dict = new Dictionary<string, int>();
        var tasks = new List<Task<Dictionary<string, int>>>();
        var producer = Task.Factory.StartNew(() =>
        {

            Parallel.ForEach(File.ReadLines(path), (line) =>
            {
                collection.Add(line);
            });
            collection.CompleteAdding();
        });

        for (int i = 0; i < 1; i++)
        {
            var consumer = Task.Factory.StartNew<Dictionary<string, int>>(() =>
            {
                var localDict = new Dictionary<string, int>();
                while (!collection.IsCompleted)
                {
                    string line;
                    if (collection.TryTake(out line))
                    {
                        Map(line, localDict);
                    }
                }
                return localDict;
            });
            tasks.Add(consumer);
        }
        int count = 0;
        while (tasks.Count > 0)
        {
            var id = Task.WaitAny(tasks.ToArray());

            var res = tasks[id].Result;
            count += res.Sum(k => k.Value);
            Aggregate(res, dict);
            tasks.RemoveAt(id);
        }
        Console.WriteLine($"Values sum : {count}");
        ShowResult(dict);
        ShowTotal(dict, "End");


    }
    public static void Map(string line, Dictionary<string, int> dict)
    {
        var parts = line.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
        var streetName = parts[3];
        if (dict.Keys.Contains(streetName))
        {
            dict[streetName]++;
        }
        else
        {
            dict.Add(streetName, 1);
        }
    }
    public static void ShowResult(Dictionary<string, int> dict)
    {

        var res = dict.OrderByDescending(r => r.Value).Take(10).ToList();

        foreach (var key in res)
        {
            Console.WriteLine($"{key.Key} - {key.Value}");
        }
    }
    public static void Aggregate(Dictionary<string, int> part, Dictionary<string, int> main)
    {

        foreach (var key in part.Keys)
        {
            if (main.Keys.Contains(key))
            {
                main[key] += part[key];
            }
            else
            {
                main.Add(key, 1);
            }
        }
    }

    public static void ShowTotal(Dictionary<string, int> dict, string mark = null)
    {
        Console.WriteLine($"{mark ?? ""} Keys: {dict.Keys.Count} - Values:{dict.Sum(s => s.Value)}");
    }

在调试时显示正确的步骤,但结果显示每个项目只有一次命中和总计不正确。


I make first steps in parallel programming. I wrote a simplest code, but it result confused. This code takes top 10 recent items with producer-consumer pattern. Only 1 consumer and 1 producer. With two consumers in works better, but incorrect too.

  public static void ProducerConsumer(string path)
    {
        var capacity = 50000;
        var collection = new BlockingCollection<string>(capacity);
        var dict = new Dictionary<string, int>();
        var tasks = new List<Task<Dictionary<string, int>>>();
        var producer = Task.Factory.StartNew(() =>
        {

            Parallel.ForEach(File.ReadLines(path), (line) =>
            {
                collection.Add(line);
            });
            collection.CompleteAdding();
        });

        for (int i = 0; i < 1; i++)
        {
            var consumer = Task.Factory.StartNew<Dictionary<string, int>>(() =>
            {
                var localDict = new Dictionary<string, int>();
                while (!collection.IsCompleted)
                {
                    string line;
                    if (collection.TryTake(out line))
                    {
                        Map(line, localDict);
                    }
                }
                return localDict;
            });
            tasks.Add(consumer);
        }
        int count = 0;
        while (tasks.Count > 0)
        {
            var id = Task.WaitAny(tasks.ToArray());

            var res = tasks[id].Result;
            count += res.Sum(k => k.Value);
            Aggregate(res, dict);
            tasks.RemoveAt(id);
        }
        Console.WriteLine($"Values sum : {count}");
        ShowResult(dict);
        ShowTotal(dict, "End");


    }
    public static void Map(string line, Dictionary<string, int> dict)
    {
        var parts = line.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
        var streetName = parts[3];
        if (dict.Keys.Contains(streetName))
        {
            dict[streetName]++;
        }
        else
        {
            dict.Add(streetName, 1);
        }
    }
    public static void ShowResult(Dictionary<string, int> dict)
    {

        var res = dict.OrderByDescending(r => r.Value).Take(10).ToList();

        foreach (var key in res)
        {
            Console.WriteLine($"{key.Key} - {key.Value}");
        }
    }
    public static void Aggregate(Dictionary<string, int> part, Dictionary<string, int> main)
    {

        foreach (var key in part.Keys)
        {
            if (main.Keys.Contains(key))
            {
                main[key] += part[key];
            }
            else
            {
                main.Add(key, 1);
            }
        }
    }

    public static void ShowTotal(Dictionary<string, int> dict, string mark = null)
    {
        Console.WriteLine($"{mark ?? ""} Keys: {dict.Keys.Count} - Values:{dict.Sum(s => s.Value)}");
    }

While debugging it shows correct steps, but result shows only one hit per item and incorrect total.


原文:https://stackoverflow.com/questions/37762334
更新时间:2022-09-15 17:09

最满意答案

请记住,显示帧的精度受显示器刷新率的限制(对于60 Hz显示器通常为17 ms,对于75 Hz显示器通常为13 ms)。 如果你没有同步到显示刷新那么你有一个不确定的延迟0到17毫秒,以添加到你使用的任何计时方法,因此准确性并不需要比10毫秒更好(甚至1毫秒可能是矫枉过正)。


Remember that the accuracy with which a frame is displayed is limited by the refresh rate of your display (typically 17 ms for a 60 Hz display, or 13 ms for a 75 Hz display). If you're not syncing to the display refresh then you have an indeterminate latency of 0 - 17 ms to add to whatever timing method you use, hence accuracy doesn't really need be much better than 10 ms (even 1 ms is probably overkill).

相关问答

更多
  • 根据计时器回调的工作结构,有一种解决方法。 如果长计时器回调正在运行长循环或对不同函数的调用序列,则可以插入drawnow()或pause(0.01)调用以使其屈服于Matlab的事件调度队列,该队列将处理挂起的句柄图形和计时器事件,包括你的其他Timer的触发器。 这有点像老派合作多任务处理,其中每个线程必须明确地将控制权交给其他线程,而不是被系统的调度程序抢占。 Matlab是关于M代码执行的单线程。 当Matlab函数运行时,引发的事件被放在事件队列中并等待函数完成并返回到命令提示符,或者drawno ...
  • 请记住,显示帧的精度受显示器刷新率的限制(对于60 Hz显示器通常为17 ms,对于75 Hz显示器通常为13 ms)。 如果你没有同步到显示刷新那么你有一个不确定的延迟0到17毫秒,以添加到你使用的任何计时方法,因此准确性并不需要比10毫秒更好(甚至1毫秒可能是矫枉过正)。 Remember that the accuracy with which a frame is displayed is limited by the refresh rate of your display (typically ...
  • 要做到这一点(使用这个一般结构),你有两个选择: 保持对象 保留对你返回的对象的引用: var obj; // ... obj = { publicMethod: publicMethod, isLoaded: false, start: start, stop: stop, }; return obj; ...并删除isLoaded变量,而是在回调中设置obj.isLoaded = true 。 现场示例: var Module = (function() { ...
  • 是的,即使没有在某处引用,计时器也会继续运行回调。 您必须为其删除计时器的事件侦听器才能将其删除。 基本上是这样的: private function destroyTimer():void { if(myTimer) { myTimer.removeEventListener(runOnce); myTimer.stop(); myTimer = null; } } Yes, a timer will continue to run cal ...
  • var initSeconds = new Date(2010, 0).getSeconds() //january 1 of 2010 , BASE_NUMBER = 5000000 ; setInterval(function() { var curSeconds = new Date().getSeconds() , elem = $('#mydisplayelem') ; elem.text(BASE_NUMBER + curSeconds - initSe ...
  • https://msdn.microsoft.com/en-us/library/vstudio/system.timers.timer(v=vs.100).aspx 如果SynchronizingObject属性为null,则会在ThreadPool线程上引发Elapsed事件。 如果Elapsed事件的处理持续时间超过Interval,则可能会在另一个ThreadPool线程上再次引发该事件。 在这种情况下,事件处理程序应该是可重入的。 你在定时器上设置SynchronizingObject吗? Han ...
  • 我想服务器回调附加到id为#updateButton的按钮? 奇怪的是,你有一个脚本触发对该按钮的单击操作,而不是每隔xx秒触发一次回调。 以下脚本将每10秒更新一次整个主体。 鉴于您实现了正确的渲染方法,这可能是一个更优雅的解决方案: html script: ( ((html jQuery: 'body') load html: [ :innerHtml | self renderOn: innerHtml ]) interval: 10000) I ...
  • 是这样的; cb = function(){ console.log("setTimeout: It's been one second!"); }; let timerExample = timers.setInterval(function() { cb(); }, 10000); // // If we change our cb to a new function it will be called in our timer // cb = function() { console.lo ...
  • 如果找不到文件,请创建一个目录。 它会阻止它循环。 Create a directory if the file is not found. it will stop it from looping.
  • 解决了使用处理程序。 伟大的工具! public void do (){ final Handler handler = new Handler (); timer.scheduleAtFixedRate (new TimerTask (){ public void run (){ handler.post (new Runnable (){ public void run (){ ...

相关文章

更多

最新问答

更多
  • h2元素推动其他h2和div。(h2 element pushing other h2 and div down. two divs, two headers, and they're wrapped within a parent div)
  • 创建一个功能(Create a function)
  • 我投了份简历,是电脑编程方面的学徒,面试时说要培训三个月,前面
  • PDO语句不显示获取的结果(PDOstatement not displaying fetched results)
  • Qt冻结循环的原因?(Qt freezing cause of the loop?)
  • TableView重复youtube-api结果(TableView Repeating youtube-api result)
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • SQL Server 2014版本支持的最大数据库数(Maximum number of databases supported by SQL Server 2014 editions)
  • 我如何获得DynamicJasper 3.1.2(或更高版本)的Maven仓库?(How do I get the maven repository for DynamicJasper 3.1.2 (or higher)?)
  • 以编程方式创建UITableView(Creating a UITableView Programmatically)
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何防止调用冗余函数的postgres视图(how to prevent postgres views calling redundant functions)
  • Sql Server在欧洲获取当前日期时间(Sql Server get current date time in Europe)
  • 设置kotlin扩展名(Setting a kotlin extension)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 如何在vim中启用python3?(How to enable python3 in vim?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • dedecms如何安装?
  • 在哪儿学计算机最好?
  • 学php哪个的书 最好,本人菜鸟
  • 触摸时不要突出显示表格视图行(Do not highlight table view row when touched)
  • 如何覆盖错误堆栈getter(How to override Error stack getter)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • USSD INTERFACE - > java web应用程序通信(USSD INTERFACE -> java web app communication)
  • 电脑高中毕业学习去哪里培训
  • 正则表达式验证SMTP响应(Regex to validate SMTP Responses)