0

我正在查看 VS2010 Concurrency Profiler 的输出,我注意到我在一些 LINQ 运算符周围遇到了一些线程争用。以下是引起争用的声明:

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

LINQ 运算符是否阻塞?在作为 Parallel.ForEach 的一部分运行的任务中使用它们时我应该更加小心吗?

4

2 回答 2

2

I assume that you are asking about LINQ to Objects, and so the Select call in your code corresponds to Enumerable.Select(..).

LINQ to Objects operators themselves do not explicitly block the executing thread. However, they do allocate memory: for example, the ToArray operator will allocate larger and larger arrays in order to buffer up the results.

And, memory allocations can result in thread blocking. When you allocate memory, the CLR or the OS may need to acquire some lock in order to locate a chunk of free memory. Even more importantly, the CLR may decide to run garbage collection (GC) any time you allocate memory, and that can result in significant thread blocking.

If server GC is a good fit for your application, you can try turning it on and see if the throughput improves. Also, you can often write non-LINQ code that performs fewer memory allocations than a LINQ to Objects query. In your particular example, I believe that LINQ to Objects will start producing the results into a small array, allocating a larger array any time the results don't fit. Your custom implementation may be able to allocate the array of the right size right at the beginning, avoiding a bunch of unnecessary allocations.

于 2011-04-26T18:53:05.827 回答
0

它不应该阻塞,但是如果您使用的是 Linq-to-SQL,如果您的查询需要很长时间才能执行,那么它可能需要特别长的时间……一般来说,任何时候您使用多线程做某事时,您都应该“更小心”或正如他们所说:“小心穿线!”

但是,如果您遇到争用问题,那么您应该真正分析您实际在做什么。Linq 不是线程安全的,因此如果您正在对可能从另一个线程更改的实体执行读/写操作,那么您应该正确同步。

于 2011-04-17T09:40:13.440 回答