I am a beginner at this thread thing and I have been hitting my head against the wall for two days. I read everywhere the Parallel.ForeEach will wait until the threads are finished before it comes out of the ForEach. I am here to tell you that is a bunch of you know what. This will just set up a bunch of tasks as scheduled and drop out of the ForEach.
So my questions are, how do I make the tasks go from scheduled to run? How do I keep in the program until completing all of the threads? This example I have below, it will just schedule the tasks and drop out of the program.
BTW, I stole the encryption part from another StackOverflow post just to give an example of a task that would take some time.
Edit - it was suggested I include a reference to the encryption code I pasted in and it is a good idea. I believe it is originally from Microsoft, but their answer is here (https://stackoverflow.com/a/273499/1352794).
Edit v2 - I have been playing around with this a bunch and using the help here (thank you) I have come up with:
Parallel.ForEach(tasks, new ParallelOptions { MaxDegreeOfParallelism = 4 }, task =>
{
task.Start();
task.Wait();
Console.WriteLine(task.Status);
});
It looks like the "Start" and "Wait" are VERY important to this. With those two commands, it is now working. I am trying to make it so this runs on a maximum of 4 threads, and I am having a hard time making sure that is the case. Any suggestions? I also hope this is the correct way to take a bunch of tasks and push them on to multiple threads.
class Program
{
static void Main(string[] args)
{
List<Task> tasks = new List<Task>();
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
tasks.Add(new System.Threading.Tasks.Task(() => DoEncryption()));
bool testbool = Parallel.ForEach(tasks, new ParallelOptions { MaxDegreeOfParallelism = 4 }, myTest =>
{
System.Threading.Tasks.Task.Run(() => myTest);
Console.WriteLine(myTest.Status);
}).IsCompleted;
Console.WriteLine("The parallel status is " + testbool);
string mymessage = System.Diagnostics.Process.GetCurrentProcess().Threads.Count.ToString();
}
private static void DoEncryption()
{
try
{
string original = "Here is some data to encrypt!";
// Create a new instance of the RijndaelManaged
// class. This generates a new key and initialization
// vector (IV).
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
myRijndael.GenerateKey();
myRijndael.GenerateIV();
// Encrypt the string to an array of bytes.
byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);
//Display the original data and the decrypted data.
Console.WriteLine("Original: {0}", original);
}
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}
}
static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decryptor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
}