在线程代码中复制列表时出错

Error when copying a List in threaded code

当我的机器负载很重时,我的线程代码出现错误。当机器负载较轻时,不会发生错误。我正在使用 VS 2013、C# 5.0 和 .NET 4.51。

代码如下:

private static readonly Object lockGetData = new Object();

public static void GetData(string symbol, out List<Tuple<double, double>> velocityLine)
{
   try
   {
      lock (lockGetData)
      {
         mData = mSymbols[symbol];
         Debug.Assert(mData != null, "Oh crap! mData is null");
         velocityLine = new List<Tuple<double, double>>(mData.velocityLine);
         return;
      }
   } 
   catch (Exception ex)
   {
      DebugPrint("GetData error.\n" + ex.Message, symbol);
      velocityLine = new List<Tuple<double, double>>();
      return 0.0;
   } 
}

我在线上遇到错误:

velocityLine = new List<Tuple<double, double>>(mData.velocityLine);

错误信息是:"Destination array was not long enough. Check destindex and length, and the array's lower bounds."

当错误发生时,当我检查"velocityLine"的长度时,它是空的。

我不明白为什么会出现此错误。任何帮助或建议将不胜感激。

查尔斯

没有完整的代码示例,不清楚如何使用 mData 集合对象。但是考虑到错误,几乎可以肯定的是,在执行 List<T> 构造函数时,该对象正在被其他线程修改,结果是该集合的长度在 List<T> 构造函数使用的时间之间发生变化它初始化后备数组的长度,以及它随后尝试将所有元素从 mData 对象复制到后备数组的时间。

同步 velocityLine 对象是不够的。您还必须同步对用于初始化它的 mData 对象的任何访问。

最后,我会注意到这里有一个 try/catch (Exception) 子句是非常糟糕的形式(假设您的版本实际上有一个有效的 return 声明,而不是这里发布的内容)。如果你只是为了调试这段代码而把它放在那里,那很好......但是现在你知道出了什么问题,你应该删除它。这将确保如果有任何其他错误,您将被迫修复它们,而不是程序神秘地随机地做一些与您想要的不同的事情。