Блокируют ли операторы LINQ вообще? - PullRequest
0 голосов
/ 16 апреля 2011

Я смотрю на выходные данные VS2010 Concurrency Profiler и замечаю, что у меня возникают некоторые разногласия по поводу некоторых операторов LINQ. Вот утверждение, вызывающее раздор:

m_dictionary.PermutableSubunits.Select(subunit => subunit.Number).ToArray()

Блокируют ли операторы LINQ? Должен ли я быть более осторожным при использовании их в Задаче, которая выполняется как часть Parallel.ForEach?

Ответы [ 2 ]

2 голосов
/ 26 апреля 2011

Я предполагаю, что вы спрашиваете о LINQ to Objects, и поэтому вызов Select в вашем коде соответствует Enumerable.Select (..).

Операторы LINQ to Objects сами не блокируют явно выполняющийся поток. Однако они выделяют память: например, оператор ToArray будет выделять все большие и большие массивы для буферизации результатов.

И, выделение памяти может привести к блокировке потока. Когда вы выделяете память, CLR или ОС может потребоваться установить блокировку, чтобы найти кусок свободной памяти. Еще важнее то, что CLR может решить запускать сборку мусора (GC) в любое время, когда вы выделяете память, и это может привести к значительной блокировке потока.

Если серверный ГХ хорошо подходит для вашего приложения, попробуйте включить его и посмотреть, улучшится ли пропускная способность. Кроме того, вы часто можете писать не LINQ-код, который выполняет меньше выделений памяти, чем запрос LINQ to Objects. В вашем конкретном примере я полагаю, что LINQ to Objects начнет выводить результаты в небольшой массив, выделяя больший массив всякий раз, когда результаты не подходят. Ваша пользовательская реализация может быть в состоянии выделить массив правильного размера в самом начале, избегая кучу ненужных выделений.

0 голосов
/ 17 апреля 2011

Он не должен блокироваться, но если вы используете Linq-to-SQL, это может занять исключительно много времени, если ваш запрос занимает много времени ... в общем, каждый раз, когда вы что-то делаете с многопоточностьювы должны быть «более осторожными» или, как говорится: «осторожно!»

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

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