Tag: task parallel library

从未完成的任务会发生什么? 他们妥善处理?

说我有以下课程: class SomeClass { private TaskCompletionSource _someTask; public Task WaitForThing() { _someTask = new TaskCompletionSource(); return _someTask.Task; } //Other code which calls _someTask.SetResult(..); } 然后在别处,我打电话 //Some code.. await someClassInstance.WaitForThing(); //Some more code //Some more code在调用_someTask.SetResult(..)之前,不会调用//Some more code 。 调用上下文在内存中等待。 但是,假设从未调用过SetResult(..) ,并且someClassInstance停止被引用并被垃圾收集。 这会造成内存泄漏吗? 或.Net自动神奇地知道需要处理调用上下文?

在并行任务期间跟踪死WebDriver实例

我看到一些使用Selenium WebDriver运行并行化嵌套循环Web压力测试的死实例怪异,简单的例子就是说,打出300个独特的页面,每个页面有100个印象。 我“成功地”使用ThreadLocal将4-8个WebDriver实例用于隔离每个任务线程,并在ParallelOptions实例上使用MaxDegreeOfParallelism来限制线程。 我只对外部循环(页面集合)进行分区和并行化,并在每个分区的“长时间运行任务”方法开头的ThreadLocal容器中检查.IsValueCreated 。 为了便于以后清理,我将每个新实例添加到由线程ID键入的ConcurrentDictionary。 无论我使用何种并行或分区策略,WebDriver实例偶尔会执行以下操作之一: 启动但从不显示url或投放展示 启动,运行任意数量的印象,然后在某些时候闲置 当其中任何一个发生时,并行循环最终似乎注意到一个线程没有做任何事情,它产生了一个新的分区。 如果n是允许的线程数,则这导致n个生产线程只有大约50-60%的时间。 清理工作最后仍然可以正常工作; 可能有2n个开放浏览器或更多,但生产性和非生产性的浏览器都得到了清理。 有没有办法监控这些无用的WebDriver实例和a)立即清除它们,加上b)让并行循环立即替换任务段,而不是像现在经常那样滞后几分钟?

强制任务到不同的核心?

Tpl和Plinq自动将工作分配给线程(在核心/ s … { 好吧,如果#threads> #cores那么,> 1个线程将在同一个核心上运行。 })。 但是,假设我有MyMethod1(){..}和MyMethod2(){..} ,我需要确保 (!)每个都运行在不同的核心上! (例如密集计算) 我找到的最近的解决方案是Plinq的.WithExecutionMode (ParallelExecutionMode.ForceParallelism) 但这是针对一种不同的情况,Plinq可能会认为按顺序而不是平行进行更好。同时,我不使用Plinq。 我只有2种方法需要在不同的核心上运行。 我该怎么做 ? ps这里有一个答案,建议使用TaskCreationOptions.LongRunning但它只是暗示TaskScheduler它应该更积极地创建线程池线程。 但是那些线程可以在同一个核心上。 我的情况要求他们处于不同的核心。 谢谢。

任务并行库 – 单核上的并行性

我正在研究WPF应用程序。 在屏幕/视图中,我必须对WCF服务进行6次调用。 这些调用中没有一个是相关的,因为它们不共享数据,也不相互依赖。 我打算使用TPL并将这6个WCF服务调用作为6个任务。 现在,应用程序可以部署在单个核心机器上,也可以部署在多个核心机器上。 我被告知在单核机器上使用TPL实际上会增加完成任务所需的时间,因为cpu调度程序会花费很多时间来拼接不同的任务。 这是真的。 如果是的话我应该继续我的设计还是我应该看看替代品。 如果我必须看看替代品,那些替代品是什么:)?

Parallel.Foreach vs Foreach和Task in local variable

当我们使用foreach和Tasks我们需要使用这样的局部变量: List TaskPool = new List(); foreach (TargetType Item in Source) { TargetType localItem = Item; TaskPool.Add(Task.Factory.StartNew(() => DoSomething(localItem))); } Task.WaitAll(TaskPool.ToArray()); 但是Parallel.Foreach怎么样,我这样使用它: Parallel.ForEach(Source, (TargetType item) => DoSomething(item)); 所以你看不到任何局部变量。 但是Parallel.Foreach如何工作? 是否没有必要引入任何局部变量? 或者如果需要,我该如何定义它? UPDATE .NET 4和.NET 4.5有什么区别吗?

数据的异步处理

在那一刻我试图组装一个异步tcp服务器来接收我想要处理的数据,提取值并插入到sql server。 我认为最好的基本概念是一旦数据被接收并确认为整个消息,那么消息应该被传递到某种集合以等待基于FIFO的处理,这将解析值并将它们插入到sql server。 我想这就是消费者/生产者模式。 我一直在寻找最好的收集/方式来做到这一点,到目前为止看到BlockingCollection,ConcurrentCollection和BufferBlock使用async / await,我认为这可能是要走的路,但说实话我不确定。 我找到的最好的例子是Stephen Cleary的博客,特别是这篇文章, http://blog.stephencleary.com/2012/11/async-producerconsumer-queue-using.html 我的主要保留意见是,我绝不想放慢速度或中断接收消息,我建议使用多个生产者/消费者示例,这可以在上面的链接中看到,但我想知道的是; 我在这个假设中是正确的,还是在我的场景中有更合适的方法。 如果我在我的假设中是正确的,那么考虑到我的用例,任何人都可以建议实现这一点的最佳方法。 任何和所有的帮助非常感谢。

如何标记TPL数据流周期完成?

在TPL数据流中给出以下设置。 var directory = new DirectoryInfo(@”C:\dev\kortforsyningen_dsm\tiles”); var dirBroadcast=new BroadcastBlock(dir=>dir); var dirfinder = new TransformManyBlock((dir) => { return directory.GetDirectories(); }); var tileFilder = new TransformManyBlock((dir) => { return directory.GetFiles(); }); dirBroadcast.LinkTo(dirfinder); dirBroadcast.LinkTo(tileFilder); dirfinder.LinkTo(dirBroadcast); var block = new XYZTileCombinerBlock(3, (file) => { var coordinate = file.FullName.Split(‘\\’).Reverse().Take(3).Reverse().Select(s => int.Parse(Path.GetFileNameWithoutExtension(s))).ToArray(); return XYZTileCombinerBlock.TileXYToQuadKey(coordinate[0], coordinate[1], coordinate[2]); }, (quad) => XYZTileCombinerBlock.QuadKeyToTileXY(quad, (z, […]

如何在addrange select语句中添加异步“await”?

我有这样的function: public async Task SampleFunction() { var data = service.GetData(); var myList = new List(); myList.AddRange(data.select(x => new SomeViewModel { Id = x.Id, DateCreated = x.DateCreated, Data = await service.GetSomeDataById(x.Id) } return myList; } 我的await不起作用,因为它只能用于标记有async修饰符的方法或lambda。 我在哪里放置async与此function?

应该何时将任务视为“长时间运行”?

在处理任务时,经验法则似乎是线程池 – 通常由例如调用Task.Run()或Parallel.Invoke() – 应该用于相对较短的操作。 在处理长时间运行的操作时,我们应该使用TaskCreationOptions.LongRunning标志,以便 – 据我所知 – 避免堵塞线程池队列,即将工作推送到新创建的线程。 但究竟什么是长期运行 ? 从时间上看,多长时间? 在决定是否使用LongRunning ,是否还要考虑除预期任务持续时间之外的其他因素,例如预期的CPU架构(频率,核心数……)或将尝试的任务数量从程序员的角度立刻运行? 例如,假设我有500个任务要在专用应用程序中处理,每个任务需要10-20秒才能完成。 我应该只使用Task.Run启动所有500个任务(例如在循环中),然后等待它们全部,可能是LongRunning ,同时保留默认的最大并发级别? 然后,如果我在这种情况下设置LongRunning ,那么与省略LongRunning相比,这不会创建500个新线程并且实际上会导致大量开销和更高的内存使用(由于额外的线程被分配)? 这假设在等待这500个任务时不会安排执行新任务。 我猜想设置LongRunning的决定取决于在给定时间间隔内对线程池发出的请求数,而LongRunning只应该用于预期比大多数线程池花费更长时间的任务 -放置任务 – 根据定义,最多只占所有任务的一小部分。 换句话说,这似乎是一个排队和线程池利用率优化问题,应该通过测试逐个解决,如果有的话。 我对么?

对于表示返回void 的操作的任务,Task.FromResult ()的替代方法是什么?

返回没有generics类型参数的任务的最佳方法是什么? 换句话说,一个任务代表一个不返回任何东西或返回void ? 换句话说,我正在寻找以下替代方案: T value = default(T); return Task.FromResult(value); // and var tcs = new TaskCompletionSource(); tcs.SetResult(value); return tcs.Task; 但对于代表不应返回任何内容的操作的任务。