I am trying to run multiple tasks in parallel (multithreaded), however, tests are showing they are still running concurrently. The code below seems to be similar to other examples I have read here on SO, along with the MS docs, its probably something I am just missing or not understanding.
Task.Run(async () =>
{
while (_runSensors)
{
var tasks = new List<Task>
{
Task.Factory.StartNew(() => {
_sensors.Find(item => item.Name == nameof(SensorA)).Refresh(); }, token),
Task.Factory.StartNew(() => {
_sensors.Find(item => item.Name == nameof(SensorB)).Refresh(); }, token),
Task.Factory.StartNew(() => {
_sensors.Find(item => item.Name == nameof(SensorC)).Refresh(); }, token)
};
await Task.WhenAll(tasks);
}
}
The signature for the 'Refresh()' method that is called is simply:
public void Refresh() { ... }
Where the internal workings are irrelevant to the question, basically reads from an input source and processes it (converts/formats/etc) and updates public properties of the sensor object.
Each of the 'sensors' above takes approximately 15-20 ms (as calculated by Stopwatch). With each sensor added to the list above, the runtime until await Task.WhenAll(tasks); is completed increases 15-20ms. ie. if there are 8 sensors added each iteration is roughly 120-160ms.
What I am trying to do is get them to run in parallel so that say 5 sensors takes approximately the same amount of time per iteration as 3 sensors. I do realize there would be some overhead with thread swapping as those numbers get higher
Edit #1 - Refresh Method from Sensor
public override void Refresh()
{
Read(Offset, Range); // Reads a portion of the screen (bitblt copy) ~8ms
_preprocesed = Preprocess(_buffer); // OpenCV methods to prep for OCR
var text = _preprocesed.ToText(_ocrOptions); // Tesseract OCR conversion ~10ms
var vals = text.Trim().Replace(" ", string.Empty).Split('/'); // Reformat
if (vals.Length != 2)
return;
int.TryParse(vals[0], out var current);
// Setter (only updates if changed INotifyPropertyChanged)
Current = current;
int.TryParse(vals[1], out var refreshCap);
// Setter (only updates if changed INotifyPropertyChanged)
RefreshCap = refreshCap;
}