私は次のメソッドを持つクラスを持っています:
public List<Bike> bikesCopy
{
get
{
List<Bike> bs;
lock (_bikes) bs = new List<Bike>(_bikes);
return bs;
}
}
別のリストのコピーを作成します、private List<Bike> _bikes;
奇妙なことは、次のエラーが表示されることです。
宛先配列の長さが足りませんでした。 destIndexと長さ、および配列の下限を確認してください。
ここで問題は何ですか?
エラーはオブジェクトにあると言えます_ bikesスレッドセーフではありません。コメントしたように、ロックされていない_ bikesオブジェクトの変更がどこかにあります。
これは、_ bikesのサイズが測定されたときに変数bsがサイズXに設定されているという、一瞬のエラーです。リストを埋めようとしている次の一瞬で、_ bikesオブジェクトのサイズが大きくなり、エラーが発生します。
だからあなたのコードを調べてください。 _ bikesオブジェクトのすべての参照を見つけ、それらがスレッドセーフで処理されることを確認します(ロックあり)。
さてあなたは試すことができます:
using System.Linq; //ToList() is an extension function defined here
...
lock(_bikes)
return _bikes.ToList();
例外の詳細は次のとおりです。 特定の場合にforeachループが機能しないのはなぜですか?
本当の答えではなく、研究のコメントです。
同じ問題にぶつかり、簡単なテストを行いました。以下のコードを試しましたが、このコードを取得して_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);
}
}
}
_
リストも配列によって支えられているので、なぜクラッシュしないのか、本当に疑問に思います。