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)
source to share
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.
source to share
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.
source to share
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.
source to share