c# ArgumentOutOfRangeException

4

我有一段代码:

    private List<...> LayPrices;
    public Decimal BestLayOdds
    {
        get
        {
            if (LayPrices.Count > 0)
            {
                return LayPrices[0].dOdds;
            }
            return 1000.0M;   
        }
    }

问题是,有时列表中存在项目,但它不会进入“if”语句。
请查看下面的调试会话图像:
https://istack.dev59.com/YLInR.webp 这怎么可能?
但是,如果我在最后一个返回语句中强制它返回第一个项目,则即使列表中有元素,我也会得到ArgumentOutOfRangeException。请查看下一个图像:
https://istack.dev59.com/DOhgN.webp 我的代码有问题还是只是愚蠢的错误?
更新:
LayPrices列表仅在类构造函数上实例化:```LayPrices = new List();```
它只在一个方法中填充了项目,其中包含以下代码:
    LayPrices.Clear();
    foreach (PriceSize priceSize in exchangePrices.availableToLay)
    {
          PriceStruct lay = new PriceStruct();
          lay.dOdds = (Decimal)priceSize.price;
          lay.dAmount = (Decimal)priceSize.size;

          LayPrices.Add(lay);
   }

并发问题和线程是我第一个怀疑的原因,所以我在lock(LayPrices)处加了锁,但问题仍然存在:

lock

所以我认为这不是并发问题。


9
LayPrices 是如何实例化和填充的?有任何线程操作吗? - Patrick Hofman
2
我可能漏掉了什么,或者我们无法从您的代码中看到问题。您能否添加LayPrices的设置?(或显示每个修改/实例化它的地方)。 - Nahuel Ianni
1
LayPrices从哪里获取输入?在上面的代码中,LayPrices对象没有被初始化。 - AkshayP
10
你是否有任何设置或填充“LayPrices”的属性获取器,这些获取器可能正在被Visual Studio调试器评估? - user743382
1
如果一切看起来正常,那么清理解决方案并重新构建它。有时候这可以解决问题。 - Shaharyar
显示剩余5条评论
2个回答

2

if语句之前的getter中放置Debug.Assert(LayPrices.Count > 0),然后您将看到List实际上是空的。

唯一合理的解释是,您要么在其他线程中填充列表并且存在竞争条件,要么在仅由调试器触发的属性getter中填充了列表(您也可以在调用堆栈中的catch子句中填充列表,但我想您自己已经想到了这一点)

为了获得更好的答案,请包括所有填充列表的代码。不只是您认为应该运行的代码,而是添加或删除列表项的所有属性、构造函数或方法。


我已经这样做了,你是正确的!断言失败了,因为列表实际上是空的。现在我必须弄清楚为什么调试告诉我它不是空的。感谢您的帮助。 - Joaquim Anacleto

1
我发现了问题。实际上是并发问题,尽管我没有显式地使用线程,我使用事件,我认为事件处理是同步的(它确实是同步的吧?)。
如果我在读取或添加列表时加锁,问题就消失了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接