Information Technology Reference
In-Depth Information
This snippet of code performs Web downloads from a series of Web sites:
foreach ( var url in urls)
{
var result = new WebClient ().DownloadData(url);
UseResult(result);
}
The DownloadData() call makes a Web synchronous request and waits
until all the data is retrieved. This algorithm will spend a lot of time wait-
ing. You can quickly change to a parallel model by using a parallel for
loop:
Parallel .ForEach(urls, url =>
{
var result = new WebClient ().DownloadData(url);
UseResult(result);
});
Parallel.ForEach() opts into a parallel processing model. This version takes
much less time than the serial version. In fact, on my dual core machine,
the speedup is roughly proportional to the number of elements in the urls
collection. Threads are spending much of their time waiting, so the Parallel
Ta s k L i b r a r y w i l l c r e a t e m o r e t h r e a d s .
Yo u c a n u s e P L I N Q a n d q u e r y s y n t a x t o p r o d u c e t h e s a m e k i n d o f r e s u l t :
var results = from url in urls.AsParallel()
select new WebClient ().DownloadData(url);
results.ForAll(result => UseResult(result));
PLINQ operates a bit differently than the Parallel Task Library's
Parallel.ForEach() support. PLINQ will use a fixed number of threads,
whereas AsParallel() will ramp the number of threads up or down to
increase throughput. You can control the number of threads in PLINQ
using ParallelEnumerable.WithDegreeOfParallelism() (see Item 35), but
Parallel.ForEach() will manage it for you. Parallel.ForEach() works best
when the load is some mixture of I/O bound and CPU bound operation.
Parallel.ForEach() will manage the number of active threads based on the
current load. When more threads are blocked waiting on I/O operations,
it will create more threads to increase throughput. When more threads are
working, it will allow the number of active threads to go down to minimize
context switching.
 
Search WWH ::




Custom Search