C# C语言中的闭包lambda表达式#

C# C语言中的闭包lambda表达式#,c#,lambda,closures,C#,Lambda,Closures,我有这种功能 function SomeFunction() { const int NUMBER_OF_CONCURENT_THREADS = 50; List<Guid> sessions = new List<Guid>(); ManualResetEvent[] doneEvents = new ManualResetEvent[NUMBER_OF_CONCURENT_THREADS]; Action<int>

我有这种功能

function SomeFunction()
{

    const int NUMBER_OF_CONCURENT_THREADS = 50;

    List<Guid> sessions = new List<Guid>();

    ManualResetEvent[] doneEvents = new ManualResetEvent[NUMBER_OF_CONCURENT_THREADS];

    Action<int> makeServiceCall = (iter) =>
    {
        var proxy = GetProxy();
        sessions.Add(proxy.GetCurrentSessionId());

        doneEvents[iter].Set();
    };

    for (int i = 0; i < NUMBER_OF_CONCURENT_THREADS; ++i)
    {
        doneEvents[i] = new ManualResetEvent(false);                

        ThreadPool.QueueUserWorkItem((o) => 
        {
            int iter = i;
            makeServiceCall(iter);
        });
    }

    WaitHandle.WaitAll(doneEvents);

    Assert.AreEqual(50, sessions.Count);
}
function SomeFunction()
{
const int concurrent线程数=50;
列表会话=新列表();
ManualResetEvent[]DoneeEvents=新的ManualResetEvent[并发线程数];
Action makeServiceCall=(iter)=>
{
var proxy=GetProxy();
sessions.Add(proxy.GetCurrentSessionId());
doneEvents[iter].Set();
};
for(int i=0;i<并发线程数;++i)
{
doneEvents[i]=新的手动重置事件(false);
ThreadPool.QueueUserWorkItem((o)=>
{
int iter=i;
makeServiceCall(iter);
});
}
WaitHandle.WaitAll(doneEvents);
Assert.AreEqual(50,sessions.Count);
}

问题是,在
doneEvents[iter].Set()时,我得到了
IndexOutOfRangeException
代码行。请问,有什么办法可以解决吗?

啊,迭代器变量上的好的ol'闭包;p

移动
int iter

int iter = i;
ThreadPool.QueueUserWorkItem((o) => {
    makeServiceCall(iter);
});
当前,您正在捕获随着循环而变化的内容,并且通常在线程启动时在循环之后。或者,使用arg
o

ThreadPool.QueueUserWorkItem((o) => {
    int iter = (int)o;
    makeServiceCall(iter);
}, i);
这将在项目排队时传递
i
的盒装副本,因此它不会更改


如果问题不清楚:捕获到lambda中的变量保留其原始声明点——这是一个完整的词汇闭包。
QueueUserWorkItem
中的
i
不是“创建此lambda时
i
的值”,而是“现在
i
的值”。在大多数情况下,
for
循环的速度将大大超过线程的创建/拾取速度,因此当线程开始时,
for
循环已经完成,
i
的值现在超出了数组的界限。

Eric Lippert写了一篇关于关闭循环变量的伟大文章。过来看