Recently, I’ve been working on a project requiring the
need to process very large quantities of data.
Many of the processes we have been writing can be broken up into
parallel tasks. While the .net
framework has supported multithreading since the beginning, the 4.0 version
introduced the System.Threading.Tasks
namespace. This is a nice collection
of classes to help make multithreaded programming a bit easier.
Looking at the MSDN documentation
You will see a number of classes. For this posting, I am going to zero-in on
the Parallel class.
Here you will find heavily overloaded methods For and ForEach,
both of these are methods to iteratively preform work on a thread. If you
have not looked at this before, it is a very welcome treat!
The first things you will add to your code are the using statements.
using System.Threading; // Thread
using System.Threading.Tasks; // Parallel
The Parallel class is found in System.Threading.Tasks,
but you may still want to use Thread,
which will require System.Threading.
The basic syntax is this…
Parallel.For(Int32,
Int32,Action<Int32>);
Argument 1, starting value (Inclusive)
Argument 2, ending value (Exclusive)
Argument 3, Action to perform
The premise is simple, you iterate just like you would a traditional for loop; however, unlike a traditional for loop, each iteration is performed in its own task (thread). I'm demonstrating a Parallel.For loop, but there is also a Parallel.ForEach.
Here is a very simple example:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ParallelSample
{
public class Program
{
public static void Main(string[]
args)
{
Parallel.For(0, 10, DoThis);
Console.Read();
}
public static void DoThis(int i)
{
//try adding a Thread.Sleep(5000);
//try adding a Thread.Sleep(5000);
Console.WriteLine("***
{0} ThreadID= {1}", i,
Thread.CurrentThread.ManagedThreadId);
}
}
}
On the other hand, using lambda expressions, you
might code something like this:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ParallelSample
{
public class Program
{
public static void Main(string[]
args)
{
Parallel.For(0, 10, i =>
{
Console.WriteLine("*** {0} ThreadID= {1}", i, Thread.CurrentThread.ManagedThreadId);
});
Console.Read();
}
}
}
This is but the very basics of the Parallel For. The example simply demonstrates how to set
your code up for multitasking iteration.
You will still need to follow the general rules for developing
multithreaded programs and implement thread safe code where applicable.
One thing I did not mention was the use of the
ParallelOptions object. This object can
provide some nifty features to your tasks, such a limiting the degrees of
parallelism with the MaxDegreeOfParallelism property. In the sample, below, I am using this object
to limit only three threads of execution at a time. This can help prevent overloading the server
with worker threads. Observe the overloaded For method. It takes the ParallelOptions object as an arguement.
public static void Main(string[]
args)
{
var po = new ParallelOptions() { MaxDegreeOfParallelism = 3 };
Parallel.For(0, 10, po, i =>
{
Console.WriteLine("*** {0} ThreadID= {1}", i,
Thread.CurrentThread.ManagedThreadId);
});
Console.Read();
}
Lastly, you may want to take into consideration, the
number of processors available. One way
to do this is to do the following:
Console.WriteLine(Environment.ProcessorCount);
When you run the examples, experiment and add additional code. Perhaps try a Thread.Sleep call and observe the output.
No comments:
Post a Comment