Following to this post, I want parallelize this method :
public IEnumerable<string> GetAllLogs(IEnumerable<IComputer> computers)
{
foreach (var cpt in computers)
{
foreach (var log in cpt.GetLogs())
{
yield return log;
}
}
}
I want the method "yield returns" a log when one of the method GetLogs is finished. If I have 4 computers which returns :
With the "sequential method", the output is :
a
b
c
d
e
1
2
3
4
5
alpha
beta
gamma
delta
epsilon
I
II
III
IV
V
And the methods runs in 20 seconds. there is a Thread.Sleep(1000)
in the GetLogs
method.
I want the output looks like this :
III
a
4
gamma
b
c
IV
5
d
II
beta
e
1
2
delta
alpha
3
epsilon
I
and runs in few seconds.
I want to the methods returns an IEnumerable
This is what you need:
public IEnumerable<string> GetAllLogsParallel(IEnumerable<IComputer> computers)
{
return computers
.AsParallel()
.SelectMany(cpt => cpt.GetLogs());
}
If you want to start processing of 4 computer
-s at the same time you can adjust the degree of parallelism like this:
public IEnumerable<string> GetAllLogsParallel(IEnumerable<IComputer> computers)
{
return computers
.AsParallel()
.WithDegreeOfParallelism(4)
.SelectMany(cpt => cpt.GetLogs());
}
Following is a simplified explanation just for understanding. To learn more about that just visit PLINQ (Parallel LINQ) at MSDN.
Well, .AsParallel()
- splits the computers
enumerable into 4 parts and starts 4 threads at the same time. Each thread executes cpt.GetLogs()
for each computer
. The result is IEnumerable<IEnumerable<string>>
- enumerable of enumerables. SelectMany()
is used to flatten this list by concatenating inner enumerables and eliminating outer ones. Results are merged back automatically into the main thread in the order of their arrival.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With