【问题标题】:Inconsistent exceptions when running loop运行循环时出现不一致的异常
【发布时间】:2021-06-10 01:48:56
【问题描述】:

最近,我创建了一个 Web 请求应用程序,用于根据给定日期检索网站上的新闻文章。我创建了一个日期集合,即 [06-07-2021、06-08-2021、06-01-2021 等],并在集合上运行了一个 for 循环并返回该日期的新闻文章。为了加快这个过程,我创建了一个在集合上运行的 Parallel.ForEach 循环,它将新闻文章存储在字典中,其中键是日期,值是文章。在 Parallel 循环中,当我尝试将键值对添加到字典中时,我会收到 *System.InvalidOperationException。它不会一直发生,所以我通常可以通过重新启动程序来解决问题。我收到的另一个异常是 **System.NullReferenceException,我认为这很奇怪,因为每个变量都被赋值,即使我的方法返回一个值,尽管如果请求有问题,则返回一个空字符串。这个异常也可以通过重启应用来解决。

我的问题是为什么在运行这个应用程序时会出现异常不一致的情况?

*更改非并发集合的操作必须具有独占访问权限。对此集合执行了并发更新并损坏了它的状态。集合的状态不再正确。

**对象引用未设置为对象的实例。

【问题讨论】:

  • 请注意不要滥用标签。大多数标签都有描述,您可以通过将鼠标悬停在它们上面来阅读,这些描述通常会概述您应该或不应该使用标签的情况。例如,[visual-studio] 问题应仅用于有关 Visual Studio 应用程序的问题,而不是在 VS 环境中编写的代码。我已经为你删除了那个标签。
  • “当我尝试将键值对添加到字典中时” - 如果它是标准字典,请参阅 this answer 关于我已将您标记为的问题的副本。如果是这种情况,您可能需要ConcurrentDictionary
  • 谢谢@Llama,我相信并发词典会解决这个问题,但这并不一定能回答我的问题。我想知道为什么 Dictionary 会如此不一致地抛出这些异常。
  • 这是一个更好的问题,可以将您的问题标记为当时的副本:stackoverflow.com/questions/1320621/…
  • 再次感谢@Llama。我并不是说你否决或关闭了这个问题,所以如果我遇到这种情况,我深表歉意。我认为提供的问题更适合作为副本。

标签: c# httpwebrequest webclient parallel.foreach


【解决方案1】:

当一个没有明确记录为线程安全的类被多个线程同时访问时,它的行为变成未定义。这意味着“任何事情”都可能发生,并且提交一份抱怨不良行为的错误报告将是无效的,因为无论发生什么都不会被该类的制造商视为错误。

“任何事情”不仅包括随机噪声异常,还包括静默数据损坏或丢失更新。

您可以深入研究Dictionary<TKey, TValue> 类的source code 并尝试了解特定异常的来源,但恕我直言,这将是徒劳的练习。您将获得的知识不太可能适用于任何现实生活场景。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-17
    • 2018-07-13
    • 2023-03-06
    • 2019-09-21
    • 1970-01-01
    相关资源
    最近更新 更多