2011-07-14 31 views
7

thực hiện một chút thử nghiệm để tìm hiểu cách hoạt động của mọi thứ. Tôi có mã sau đây ...Biến riêng tư trong các tác vụ .net 4.0

for (int i = 0; i < 20; i++) 
{ 
     Task.Factory.StartNew(() => MethodTest(i)); 
} 

Tôi tự hỏi tại sao MethodTest nhận được int 20 hầu như luôn luôn (trừ khi tôi bước qua trình gỡ lỗi).

Rõ ràng có điều gì đó thiếu trong hiểu biết của tôi khi tôi giả định rằng khi 'i' được chuyển, nó sẽ là một phần của bộ nhớ cục bộ của chuỗi được quản lý.

Trả lời

15

Bạn đang bế trên biến vòng lặp - thử điều này:

for (int i = 0; i < 20; i++) 
{ 
     int x = i; 
     Task.Factory.StartNew(() => MethodTest(x)); 
} 

Điều quan trọng cần hiểu là bạn đang tạo ra một đóng qua biếnikhông giá trị hiện tại của nó.

Khi thời gian nhóm chủ đề bắt đầu chuỗi đầu tiên (chúng lần đầu tiên nằm trong hàng đợi), biến số i sẽ gần như chắc chắn là 20 khi bạn đã thoát ra khỏi vòng lặp. Giờ mỗi chuỗi được bắt đầu sẽ xem xét giá trị của biến số itại thời điểm đó.

Sửa lỗi được đề xuất là tạo biến mới bên trong phạm vi phạm vi vòng lặp và gán giá trị hiện tại là i cho biến đó. Vì một biến mới được sử dụng trên mỗi lần lặp của vòng lặp mà mỗi chuỗi được tạo ra bây giờ đóng trên biến "riêng" của nó, được phân lập và sẽ không thay đổi.

Tham chiếu chuẩn để giải thích những gì đang diễn ra là "Closing over the loop variable considered harmful".

+1

+1 Câu hỏi hay, câu trả lời hay. –

+0

Cảm ơn, thời gian để điền vào một số khoảng trống kiến ​​thức, không có ý tưởng nơi để chỉ đạo Google-Fu của tôi. :) – RekrowYnapmoc

+0

Chỉnh sửa: dưới dạng ghi chú cho người đọc trong tương lai. Điều này sẽ được thay đổi trong C# 5 để đóng trên biến vòng lặp sẽ không yêu cầu bước bổ sung này. – RekrowYnapmoc

Các vấn đề liên quan