相关疑难解决方法(0)

限制通过并行任务库运行的活动任务数的最佳方法

考虑一个包含大量需要处理的作业的队列.队列限制一次只能获得1个工作,无法知道有多少工作.这些作业需要10秒才能完成,并且需要大量等待来自Web服务的响应,因此不受CPU限制.

如果我使用这样的东西

while (true)
{
   var job = Queue.PopJob();
   if (job == null)
      break;
   Task.Factory.StartNew(job.Execute); 
}
Run Code Online (Sandbox Code Playgroud)

然后,它会以比完成它们更快的速度从队列中快速弹出作业,耗尽内存并堕落.> <

我不能使用(我不认为)ParallelOptions.MaxDegreeOfParallelism因为我不能使用Parallel.Invoke或Parallel.ForEach

我找到了3个替代方案

  1. 用.替换Task.Factory.StartNew

    Task task = new Task(job.Execute,TaskCreationOptions.LongRunning)
    task.Start();
    
    Run Code Online (Sandbox Code Playgroud)

    这似乎在某种程度上解决了这个问题,但我不清楚这是做什么的,如果这是最好的方法.

  2. 创建一个限制并发度的自定义任务调度程序

  3. 使用类似BlockingCollection的东西在启动时将作业添加到集合中,并在完成时删除以限制可以运行的编号.

#1我必须相信自己做出正确的决定,#2 /#3我必须计算出自己可以运行的最大数量的任务.

我是否理解正确 - 这是更好的方式,还是有另一种方式?

编辑 - 这是我从下面的答案,生产者 - 消费者模式中得出的结果.

除了整体吞吐量目标不是要比可以处理的更快地使作业出列并且没有多个线程轮询队列(这里没有显示但是这是非阻塞的操作并且如果从多个地方以高频率轮询将导致巨大的交易成本) .

// BlockingCollection<>(1) will block if try to add more than 1 job to queue (no
// point in being greedy!), or is empty on take.
var BlockingCollection<Job> jobs = …
Run Code Online (Sandbox Code Playgroud)

.net c# task-parallel-library

36
推荐指数
4
解决办法
4万
查看次数

TPL中的最大任务?

我想在Windows Azure上的Worker进程中使用TPL.我想在队列中添加一个IJob,这有一个Run方法,因此worker将包含:

loop get item off queue使用TPL调用IJob.Run,​​这是一个异步调用

但我有点担心我可以添加到TPL的最大项目?如果需要,我很乐意构建我自己的某种TPL池,只需检查它的功能.

干杯,灰.

multithreading worker-process azure plinq task-parallel-library

6
推荐指数
1
解决办法
2250
查看次数

如何尽快有效地发出数千个Web请求

我需要从C#控制台应用程序发出100,000个轻量级(即小的Content-Length)Web请求。我这样做的最快方法是什么(即在最短的时间内完成所有请求),我应该遵循哪些最佳实践?我无法解雇并忘记,因为我需要捕获响应。

大概我想使用asyncWeb请求方法,但是我想知道存储所有Task连续和编组的开销会产生什么影响。

内存消耗不是一个整体问题,目标是速度。

大概我也想利用所有可用的内核。

所以我可以做这样的事情:

Parallel.ForEach(iterations, i =>
{
    var response = await MakeRequest(i);
    // do thing with response
});
Run Code Online (Sandbox Code Playgroud)

但这不会让我比内核数量更快...

我可以:

Parallel.ForEach(iterations, i =>
{
    var response = MakeRequest(i);
    response.GetAwaiter().OnCompleted(() =>
    {
        // do thing with response
    });
});
Run Code Online (Sandbox Code Playgroud)

但是如何使我的程序在ForEach。握住所有TasksWhenAll荷兰国际集团他们觉得胀,是否有任何现有的模式或佣工有某种任务队列?

有什么方法可以使情况变得更好,如何处理节流/错误检测?例如,如果远程端点响应缓慢,我不想继续向其发送垃圾邮件

我了解我也需要这样做:

ServicePointManager.DefaultConnectionLimit = int.MaxValue
Run Code Online (Sandbox Code Playgroud)

还有什么需要的吗?

c# concurrency asynchronous

5
推荐指数
1
解决办法
414
查看次数