63

我有一个具有以下方法的类:

public List<Bike> bikesCopy 
{
     get 
     { 
       List<Bike> bs;
       lock (_bikes) bs = new List<Bike>(_bikes);
       return bs;
     }
}

这会复制另一个列表,private List<Bike> _bikes;

现在奇怪的是,我收到以下错误:

目标数组不够长。检查 destIndex 和长度,以及数组的下限。

这里有什么问题?

4

4 回答 4

112

我会说错误在于对象_bikes不是线程安全的。正如所评论的,某处存在未锁定的_bikes对象的修改。

当测量_bikes的大小时,变量bs设置为大小 X,这是一个瞬间错误。在即将填满列表的下一瞬间,_bikes对象的大小增加了,出现了错误。

所以检查你的代码。查找您的_bikes对象的所有引用,并确保它们是线程安全处理的(带锁)。

于 2013-01-02T08:23:36.370 回答
6

那么你可以尝试:

using System.Linq; //ToList() is an extension function defined here
...
lock(_bikes)
    return _bikes.ToList();

此处讨论了异常的详细信息:为什么 foreach 循环在某些情况下不起作用?

于 2012-04-28T08:59:57.920 回答
5

发生此错误是因为多个线程在单个列表中添加项目。默认情况下,列表不是线程安全的解决方案。在多线程代码中,建议只从列表中读取,而不是写入。

如此处所述:

如果您只是从共享集合中读取,那么您可以使用 System.Collections.Generic 命名空间中的类。

更好地使用像System.Collections.Concurrent命名空间这样的线程安全解决方案,它提供了ConcurrentBagConcurrentDictionaryConcurrentQueueConcurrentStack等实现。

例如:

public ConcurrentBag<Bike> bikesCopy 
{
     get => new ConcurrentBag<Bike>()
}
于 2020-05-06T05:01:02.570 回答
0

不是真正的答案,更多的是研究评论。

我遇到了同样的问题并进行了快速测试。我尝试使用下面的代码,但无法让此代码抛出ArgumentException: Destination array was not long enough. 但是当我.ToList()从行中删除

return allLines.ToList().ToArray();

它立即崩溃。

这是演示代码,甚至 IDE 都告诉我,我应该删除该ToList()调用,因为它看起来是多余的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main() {

            List<string> thelist = new List<string>();

            Thread producer = new Thread(() => {
                while (true) {
                    thelist.Add("a" + DateTime.Now);
                }
            });

            Thread transformer = new Thread(() => {
                while (true) {
                    string[] thearray = thelist.ToList().ToArray();
                    Console.WriteLine(thearray.Length);
                }
            });
            producer.Start();
            transformer.Start();
            Console.ReadKey(true);
        }
    }
}

我真的很想知道,为什么它不会崩溃,因为 List 也由数组支持。

于 2018-02-12T15:42:29.707 回答