Vấn đề là bạn không thể gọi List.Add()
đồng thời trên nhiều chuỗi. Nếu bạn cần bộ sưu tập chủ đề an toàn, hãy xem không gian tên System.Collections.Concurrent
.
Nếu bạn đột nhập vào trình gỡ lỗi khi bạn nhận được một ngoại lệ, bạn sẽ thấy rằng i
là không lớn hơn array.Length
, nhưng thay vào đó một sức mạnh của 2 đó là đáng kể ít hơn array.Length
. Điều gì xảy ra là List
bắt đầu với một mảng trống của một cái gì đó giống như 4 yếu tố. Bất cứ khi nào bạn thêm một phần tử vào một danh sách có mảng đầy, nó tạo ra một mảng dài gấp đôi chiều dài của mảng cũ, sao chép các phần tử cũ vào nó, và lưu trữ mảng mới.
Bây giờ, hãy nói rằng danh sách của bạn có tối đa 31 phần tử (có nghĩa là nó có không gian cho một phần tử khác) và hai chuỗi sẽ cố gắng thêm phần tử thứ 32. Cả hai đều sẽ thực thi mã như thế này:
if (_size == _items.Length)
{
EnsureCapacity(_size + 1);
}
_items[_size++] = item;
Đầu tiên họ cả hai sẽ thấy rằng _size
(31) không phải là _items.Length
(32), vì vậy cả hai đều thực hiện _size++
. Chủ đề đầu tiên sẽ nhận được 31 (chỉ số chính xác của phần tử thứ 32) và thay đổi _size
thành 32. Chuỗi thứ hai sẽ nhận được 32 và cố gắng lập chỉ mục _items[32]
, cung cấp cho bạn ngoại lệ của bạn vì nó đang cố gắng truy cập vào phần tử thứ 33 của 32 mảng phần tử.
Câu trả lời hay. Tôi ước tôi có thể bỏ phiếu lên gấp đôi. Tôi sẽ tham khảo điều này trên bài đăng blog tiếp theo của tôi; Tôi hy vọng bạn không nhớ. –
+1 câu trả lời tuyệt vời tuyệt vời, cảm ơn gabe! – andy