Felice Pollano
Felice Pollano

Reputation: 33252

Lambda expression, outer variables in multithread

Lets take this code:

public void Hit(int npage)
        {
            bool fetch = false;
            lock (pagesHit)
            {
                if (!pagesHit.Contains(npage))
                {
                    pagesHit.Add(npage);
                    fetch = true;
                }
            }
            if (fetch)
            {
                pageFiller.Completed += (s, e) =>
                    {
                        lock (pagesHit)
                        {
                            pagesHit.Remove(npage);
                        }
                    };
            }

        }

this function can be called from different threads. The goal is obviously to avoid fetching a page that is already scheduled for fetch. The filler object exposes an event that is subscribed via a lambda expression. My question is: can we say that the parameter npage is correctly handled in multithread scenario ? better: each event subscription receive its own npage parameter, or the last npage seen is propagate to all events ?

Upvotes: 6

Views: 883

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1062915

Variable capture happens per the declaration scope of npage. The parameter npage is declared at the method level, and does not change within that method - so indeed, the use of npage is entirely thread-safe.

The problem you are avoiding would occur if you were changing a variable within its declared scope, typically a loop - i.e.

for(int npage = 0; npage < 100 ; npage++)
    Foo( (s,e) => DoSomething(npage) ); // not safe; npage shared between all

however, by breaking it into a method you avoid this, i.e.

for(int i = 0; i < 100; i++)
    Hit(i);
...
void Hit(int npage) {
    Foo( (s,e) => DoSomething(npage) ); // safe; npage is per-call
}

Upvotes: 7

Mat&#237;as Fidemraizer
Mat&#237;as Fidemraizer

Reputation: 64943

Each Hit method invoke will have different values for npage reference.

In other words, each thread invoking this method will have its own npage.

That's because, for every thread invoking this method, its operations and event handler subscription will take place in different scopes, so, npage reference will point to scope's value.

Upvotes: 2

Related Questions