Лямбда-выражение, внешние переменные в многопоточности - PullRequest
6 голосов
/ 11 октября 2011

Давайте возьмем этот код:

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);
                        }
                    };
            }

        }

эта функция может быть вызвана из разных потоков.Очевидно, что цель состоит в том, чтобы избежать получения страницы, которая уже запланирована для получения.Объект-заполнитель предоставляет событие, которое подписывается с помощью лямбда-выражения.Мой вопрос: можем ли мы сказать, что параметр npage правильно обрабатывается в многопоточном сценарии?лучше: каждая подписка на событие получает свой собственный параметр npage , или последний npage распространяется на все события?

Ответы [ 2 ]

7 голосов
/ 11 октября 2011

Переменная происходит в соответствии с областью объявления из npage. Параметр npage объявляется на уровне метода и не изменяется в этом методе, поэтому использование npage является полностью поточно-безопасным.

Проблема, которую вы избегаете, возникла бы, если бы вы изменили переменную в пределах объявленной области, обычно это цикл - т.е.

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

однако, разбивая его на метод, вы избегаете этого, т.е.

for(int i = 0; i < 100; i++)
    Hit(i);
...
void Hit(int npage) {
    Foo( (s,e) => DoSomething(npage) ); // safe; npage is per-call
}
2 голосов
/ 11 октября 2011

Каждый вызов метода Hit будет иметь различные значения для ссылки npage .

Другими словами, каждый поток, вызывающий этот метод, будет иметь свой собственный npage .

Это связано с тем, что для каждого потока, вызывающего этот метод, его операции и подписка на обработчик событий будут проходить в разных областях, поэтому ссылка npage будет указывать на значение области.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...