这个问题在这里已经有了答案:
9年前关闭。
Possible Duplicate:
Parallel.ForEach vs Task.Factory.StartNew
ThreadPool 中运行大约 1,000 个任务每晚一次(这个数字将来可能会增加)。每个任务都在执行长时间运行的操作(从 Web 服务读取数据)并且是 非 CPU 密集型 . Async I/O不是此特定用例的选项。IList<string>参数,我需要DoSomething(string x) .我试图在以下两个选项之间进行选择:IList<Task> tasks = new List<Task>();
foreach (var p in parameters)
{
tasks.Add(Task.Factory.StartNew(() => DoSomething(p), TaskCreationOptions.LongRunning));
}
Task.WaitAll(tasks.ToArray());
Parallel.ForEach(parameters, new ParallelOptions {MaxDegreeOfParallelism = Environment.ProcessorCount*32}, DoSomething);
TaskCreationOptions.LongRunning 用法之间的比较和 MaxDegreeOfParallelism = Environment.ProcessorCount * SomeConstant .
最佳答案
也许你不知道这一点,但Parallel 中的成员类只是 Task 周围的简单(复杂)包装器对象。如果您想知道,Parallel类创建 Task对象 TaskCreationOptions.None .然而,MaxDegreeOfParallelism无论将什么创建选项传递给任务对象的构造函数,都会影响这些任务对象。TaskCreationOptions.LongRunning给底层证券一个“提示”TaskScheduler它可能会因线程的超额订阅而表现得更好。超额订阅适用于具有高延迟的线程,例如 I/O,因为它会将多个线程(是的线程,而不是任务)分配给单个内核,以便它始终有事可做,而不是等待当线程处于等待状态时要完成的操作。关于 TaskScheduler使用 ThreadPool ,它将在自己的专用线程上运行 LongRunning 任务(唯一一种每个任务都有一个线程的情况),否则它将正常运行,并进行调度和工作窃取(真的,无论如何你都想要)MaxDegreeOfParallelism控制并发操作运行的数量。这类似于指定数据将被分割成和处理的最大分区数。如 TaskCreationOptions.LongRunning能够被指定,所有这些都会限制一次运行的任务数量,类似于 TaskScheduler其最大并发级别设置为该值,similar to this example .
您可能需要 Parallel.ForEach .但是,添加 MaxDegreeOfParallelism等于这么高的数字实际上并不能保证同时运行那么多线程,因为任务仍然由 ThreadPoolTaskScheduler 控制。 .该调度程序会将同时运行的线程数尽可能减少,我认为这是两种方法之间最大的区别。您可以编写(并指定)自己的 TaskScheduler这将模仿最大程度的并行行为,并两全其美,但我怀疑您是否有兴趣做某事。
我的猜测是,根据延迟和您需要执行的实际请求数量,使用任务在许多(?)情况下会表现得更好,尽管最终会使用更多内存,而并行在资源使用方面将更加一致。当然,异步 I/O 的性能会比这两个选项中的任何一个都好得多,但我知道您不能这样做,因为您使用的是遗留库。因此,不幸的是,无论您选择哪一个,您都会遇到平庸的表现。
一个真正的解决方案是找出一种方法来实现异步 I/O;因为我不了解情况,所以我认为我没有比这更有帮助的了。您的程序(读取、线程)将继续执行,内核将等待 I/O 操作完成(这也称为使用 I/O 完成端口)。因为线程不处于等待状态,所以运行时可以在更少的线程上做更多的工作,这通常会以内核数和线程数之间的最佳关系结束。添加更多线程,如我所愿,并不等同于更好的性能(实际上,由于上下文切换之类的事情,它通常会损害性能)。
然而,这整个答案对于确定您的问题的最终答案是无用的,尽管我希望它能给您一些需要的方向。在您对其进行分析之前,您不会知道什么表现更好。如果您不同时尝试它们(我应该澄清我的意思是没有 LongRunning 选项的任务,让调度程序处理线程切换)并分析它们以确定最适合您的特定用例的方法,那么您就是在卖空自己。
关于c# - Task.Factory.StartNew 或 Parallel.ForEach 用于许多长时间运行的任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10687850/
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
当我使用has_one时,它工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里
我正在使用带有Rails的Devise,我想添加一个方法“getAllComments”,所以我这样写:classUser在我的Controller中:defdashboard@user=current_user@comments=@user.getAllComments();end当我访问我的url时,我得到了undefinedmethod`getAllComments'for#我做错了什么?谢谢 最佳答案 因为getAllComments是一个类方法,而您正试图将其作为实例方法访问。您要么需要访问它:User.getAllCom