gpt4 book ai didi

c# - ConcurrentQueue 和 Parallel.ForEach

转载 作者:行者123 更新时间:2023-12-04 09:29:00 27 4
gpt4 key购买 nike

我有一个 ConcurrentQueue,其中包含我需要获取其来源的 URL 列表。当使用 Parallel.ForEach 和 ConcurrentQueue 对象作为输入参数时,Pop 方法将不起作用(应该返回一个字符串)。

我正在使用 Parallel 并将 MaxDegreeOfParallelism 设置为 4。我真的需要阻止并发线程的数量。使用并行队列是多余的吗?

提前致谢。

// On the main class
var items = await engine.FetchPageWithNumberItems(result);
// Enqueue List of items
itemQueue.EnqueueList(items);
var crawl = Task.Run(() => { engine.CrawlItems(itemQueue); });

// On the Engine class
public void CrawlItems(ItemQueue itemQueue)
{
Parallel.ForEach(
itemQueue,
new ParallelOptions {MaxDegreeOfParallelism = 4},
item =>
{

var worker = new Worker();
// Pop doesn't return anything
worker.Url = itemQueue.Pop();
/* Some work */
});
}

// Item Queue
class ItemQueue : ConcurrentQueue<string>
{
private ConcurrentQueue<string> queue = new ConcurrentQueue<string>();

public string Pop()
{
string value = String.Empty;
if(this.queue.Count == 0)
throw new Exception();
this.queue.TryDequeue(out value);
return value;
}

public void Push(string item)
{
this.queue.Enqueue(item);
}

public void EnqueueList(List<string> list)
{
list.ForEach(this.queue.Enqueue);
}
}

最佳答案

如果您要做的只是首先从单个线程向其添加项目,然后在 ConcurrentQueue<T> 中对其进行迭代,则您不需要 Parallel.ForEach() 。一个普通的 List<T> 就足够了。

此外,您对 ItemQueue 的实现非常可疑:

  • 它继承自 ConcurrentQueue<string> 并且还包含另一个 ConcurrentQueue<string> 。这没有多大意义,令人困惑且效率低下。
  • ConcurrentQueue<T> 上的方法经过精心设计,是线程安全的。您的 Pop() 不是线程安全的。可能发生的情况是您检查 Count ,注意它是 1,然后调用 TryDequeue() 并且没有得到任何值(即 value 将是 null ),因为另一个线程在两次调用之间的时间内从队列中删除了该项目。
  • 关于c# - ConcurrentQueue 和 Parallel.ForEach,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37768526/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com