Are these two pieces of code using IQueryable and .AsParallel?

I'm working on some pretty simple TPL code and I ran into a situation where I was curious if the following two snippets were equivalent:

myEnumerable.AsParallel().Select(e =>
{
    //do some work that takes awhile
    return new Thing(e);
}

myEnumerable.Select(e =>
{
    //do some work that takes awhile
    return new Thing(e);
}.AsParallel()

      

Also, if they are essentially equivalent, is their equivalence something that might change as defined by the TPL interface using IEnumerable extension methods? Or am I just setting myself up to break code when upgrading to .NET V {Whatever}?

For background myEnumerable

is an EF table (entity) which I haven't listed yet (toured DB).

My desired behavior is for the DB call to be done synchronously, return a list and work with a parallel list (create a bunch of web service calls on the list in parallel)

+3


source to share


3 answers


I was curious if the following two snippets are equivalent

No, it is not. Your previous code will try to split IEnumerable

to execute in parallel. The latter code will project the elements sequentially onto yours Select

and get filtered IEnumerable

. Only what happens after AsParallel

will run in parallel.

Please note that LINQ-To-Entities does not work with AsParallel

. This will usually cause your code to run slower and then be consistent. Also, DbContext

it is not thread safe. This code can potentially do more harm than good.



What you can do is query the database first, and once the data is in memory, use AsParallel

.

My desired behavior is for the DB call to be done synchronously, List backwards and use a list in parallel (create a bunch of web pages the service calls in the list in parallel)

If you want to make multiple web service calls across the returned data, you can use the natural asynchronous API that exists to make such requests. For example, if you are requesting an HTTP endpoint, you can use HttpClient

and use it in combination with async-await

and execute requests concurrently, without the need for additional threads.

+5


source


Only what happens after AsParallel

is parallel. All of this is primarily just a serial input stream for a parallel request (exception: if the input is already a parallel request, it will be treated as such).

PLINQ cannot parallelize an existing query because it does not have the ability to parse it. The input is opaque IEnumerable

.

My desired behavior is for the DB call to be done synchronously, return a list, and work on a parallel list



Use the first piece of code.

make a bunch of web service calls on the list in parallel

TPL is terrible at choosing the optimal degree of parallelism for IO-related tasks. Use WithDegreeOfParallelism

to select the appropriate DOP for your specific I / O load.

+2


source


No, they are not equivalent.

The first expression will run in Select

parallel when consumed.

The second expression will do the work in Select

a single thread to create items for parallel execution. What you are doing to use the second expression will run in parallel, but it will probably be something trivial that cannot be parallelized.

+2


source







All Articles