gpt4 book ai didi

c# - 在以下情况下,我应该使用线程安全集合吗?

转载 作者:行者123 更新时间:2023-12-03 13:18:36 25 4
gpt4 key购买 nike

我正在从网站上抓取内容。我有一个async方法,该方法以递归方式访问页面并从页面中抓取内容。在此递归函数中,我传递了HashSetListList用于收集所有页面的内容,而Hashset用于存储已访问的链接,以便我们不再访问它们。此功能的相关部分如下:

public async Task ScrapeContentRecAsync(string uri, List<Content> allContent, HashSet<string> alreadyVisited) {
...
var pageHtml = await httpClient.GetStringAsync(uri);
alreadyVisited.Add(uri);
...
allContent.Add(someContent);
...
var newLinks = FindAllCrawlableLinks(pageHtml);
foreach(var newLink in newLinks) {
await ScrapeContentRecAsync(newLink, allContent, alreadyVisited);
}
}

如您所见,我正在等待每个可以删除的新链接(不要通过启动并行任务/并行调用来建议优化,因为有人要求我不要这样做)。因此,基本上,一旦找到新的链接,我们就会对其进行递归。新的调用将新的抓取数据添加到 allContent列表中,新的链接也添加到 alreadyVisited中。简单来说,它就是网页树的 preorder DFS

该应用程序是一个控制台应用程序,因此没有 SynchronizationContext和默认的 TaskScheduler,即 await之后的代码将在线程池线程上执行。

现在,按照旧的方式,只要有多个线程添加到列表中,我们就使用锁,以确保仅一个线程添加到列表中,并且该锁还确保对 protected 变量的任何更改对其他线程可见。

因为我的延续可以在任何线程池线程上执行,所以不同的线程有可能处理递归调用并添加到列表和哈希集集合中。
  • 对一个线程池线程上的集合所做的更改是否对其他线程可见?
  • 在上述情况下会不会存在并发问题?
  • 如果我将并行启动多个递归调用(优化),那么肯定会需要线程安全收集吗?
  • 最佳答案

    Since, my continuations can be executed on any thread pool thread, there is a chance that different threads are handling the recursive calls and adding to both the list and hashset collection.



    是的。

    Will the changes made to the collections one thread pool thread visible to other threads?



    是的。 await为您插入适当的线程屏障。

    Can there be concurrency issues in the above scenario?



    否。原样的代码是异步的,但是是串行的。

    If I would have launched multiple recursive calls in parallel (optimisation), then would I have surely needed a thread safe collection?



    是的。异步并发将需要线程安全收集或锁定。

    关于c# - 在以下情况下,我应该使用线程安全集合吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62340867/

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