Tôi đã phương pháp sau:Tại sao C# không bảo toàn ngữ cảnh cho một cuộc gọi đại biểu ẩn danh?
static Random rr = new Random();
static void DoAction(Action a)
{
ThreadPool.QueueUserWorkItem(par =>
{
Thread.Sleep(rr.Next(200));
a.Invoke();
});
}
bây giờ tôi gọi đây là trong một vòng lặp for như thế này:
for (int i = 0; i < 10; i++)
{
var x = i;
DoAction(() =>
{
Console.WriteLine(i); // scenario 1
//Console.WriteLine(x); // scenario 2
});
}
trong kịch bản 1 đầu ra là: 10 10 10 10 ... 10
trong kịch bản 2 đầu ra là: 2 6 5 8 4 ... 0
(hoán vị ngẫu nhiên từ 0 đến 9)
Bạn giải thích điều này như thế nào? C# không được bảo tồn các biến (ở đây i
) cho cuộc gọi đại biểu ẩn danh?
Nhưng bảo toàn ('chụp') biến * * i là * chính xác * điều gì đang xảy ra! Những gì * không * xảy ra, mặc dù bạn muốn nó, được giữ lại * giá trị ** ** của 'i' tại thời điểm đại biểu được thiết lập *. – AakashM
Ngẫu nhiên, ReSharper sẽ cảnh báo bạn về [Truy cập để đóng cửa sửa đổi] (http://confluence.jetbrains.net/display/ReSharper/Access+to+modified+closure) khi được trình bày với mã này; bạn có thể tìm thấy lời giải thích hữu ích. – AakashM
http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx –