I am new to async and parallel programming and my question revolves around attempting to run a method that takes a couple parameters, and then execute that method in parallel. I need to run this in parallel because the method being called is updating PLC's on my factory floor. If it is down synchrounsly, this process can take nearly 10 minutes because of how many there are. I am able to get the method to run once, using the last PLC in my custom class, but won't run for the other PLC's in my list. Sample code below:
List<Task> task = new List<Task>();
foreach(PLC plc in PlcCollection)
{
string plcName = plc.Name;
string tagFormat = plc.TagFormat
tasks.Add(Task.Run(async () => await MakeTags(plcName, tagFormat)));
}
Parallel.ForEach(tasks, task => task.Start());
// Code to be done after tasks are complete
public async Task MakeTags(string plcName, string tagFormat)
{
//Code to update the PLC's
}
The method makeTags works like it should when called - it updates the PLC correctly. But it only runs once, and only for one of my PLC values. I have also tried Task.WhenAll(tasks)
instead of the Parallel.ForEach
, with the same problem. Does anyone have any advice and feedback on what I am doing wrong and anything that I could try?
Thanks!
EDIT: To clarify - I am expecting the MakeTags method to be executed in parallel for however many PLC's there are in the PlcCollection (the number will be variable). What I am getting is that the MakeTags method is only being called once, for one PLC element, when there are multiple PLC's in the collection. This process is started from a web app and then the server takes care of the rest. No UI elements are being updated or changed. It's all behind the scenes work.
EDIT 2: See below for a screenshot of the Debugger. In this example 2 PLC's (TTC_WALL and RR_HEPA_EE) are loaded into my list of tasks. However, only the RR_HEPA_EE is processed and then the program completes without an exception being thrown.
Edit 3: I made changes and now code looks like the following:
List<Task> task = new List<Task>();
foreach(PLC plc in PlcCollection)
{
//plcName and tagFormat are just strings
tasks.Add(MakeTags(plcName, tagFormat);
}
Task.WhenAll(tasks).ContinueWith(t =>
{
//Code to do
Console.WriteLine("****PLC Update Complete*****");
});
return; //program ends
public async Task MakeTags(string plcName, string tagFormat)
{
await Task.Run(() =>
{
Console.WriteLine("Updating PLC " + plcName);
//Code to update the PLC's
Console.WriteLine("PLC Updated for :" + plcName);
});
return;
}
However I am still getting only one of the tasks to run. Debugger screenshot below, showing only 1 of the 2 PLC's were updated. I should be seeing a console line saying "PLC Updated for TTC_WALL" as well.