简单的生产者 - 消费者示例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
最满意答案
请记住,显示帧的精度受显示器刷新率的限制(对于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 ...
-
准确的连续定时器回调(Accurate continuous timer callback)[2022-12-05]
请记住,显示帧的精度受显示器刷新率的限制(对于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 ... -
定时器(回调)在揭示模块内更新公共属性(Timer (callback) inside a revealing module to update public property)[2022-07-20]
要做到这一点(使用这个一般结构),你有两个选择: 保持对象 保留对你返回的对象的引用: 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 ...
-
定时器回调的C#线程生命(C# thread life of timer callback)[2023-09-07]
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 ...
-
定时器连续循环(Timer Continuous Looping)[2021-09-07]
如果找不到文件,请创建一个目录。 它会阻止它循环。 Create a directory if the file is not found. it will stop it from looping. -
定时器与回调(Timer with callback)[2022-11-13]
解决了使用处理程序。 伟大的工具! public void do (){ final Handler handler = new Handler (); timer.scheduleAtFixedRate (new TimerTask (){ public void run (){ handler.post (new Runnable (){ public void run (){ ...