2
\$\begingroup\$

I have an application in which I have multiple slow running prerequisite methods I need to call in order to have the data I need to continue.

To try to speed this up I am doing this:

Dictionary<string, string> processOptions = null;
Dictionary<string, string> businessAreas = null;
Dictionary<string, string> requirementLevels = null;
List<TemplateSection> sections = null;
List<TemplateVersion> versions = null;

var prerequisiteTasks = new List<System.Threading.Tasks.Task>();

prerequisiteTasks.Add(new System.Threading.Tasks.Task(() => sections = GetSectionsInTreeForm(latestVersionGuid)));
prerequisiteTasks.Add(new System.Threading.Tasks.Task(() => versions = GetTemplateVersions(templateId)));
prerequisiteTasks.Add(new System.Threading.Tasks.Task(() => processOptions = GetOptionSetProcessPhaseTypes()));
prerequisiteTasks.Add(new System.Threading.Tasks.Task(() => businessAreas = GetOptionSetBusinessAreaTypes()));
prerequisiteTasks.Add(new System.Threading.Tasks.Task(() => requirementLevels = GetOptionSetRequirementLevelTypes()));

prerequisiteTasks.ForEach(x => x.Start());
System.Threading.Tasks.Task.WaitAll(prerequisiteTasks.ToArray());

Each of the methods above can take anything from 2-5 seconds to complete. Is there a nicer way of doing this, or is this something I shouldent do?

P.S. the code as is works great and decreases the time used by around 30%.

\$\endgroup\$
5
\$\begingroup\$

Another option is Parallel.Invoke:

Dictionary<string, string> processOptions = null;
Dictionary<string, string> businessAreas = null;
Dictionary<string, string> requirementLevels = null;
List<TemplateSection> sections = null;
List<TemplateVersion> versions = null;


Parallel.Invoke(() => sections = GetSectionsInTreeForm(latestVersionGuid),
                () => versions = GetTemplateVersions(templateId),
                () => processOptions = GetOptionSetProcessPhaseTypes(),
                () => businessAreas = GetOptionSetBusinessAreaTypes(),
                () => requirementLevels = GetOptionSetRequirementLevelTypes());

It should be pointed out that these tasks run in threads from the thread pool (in both cases: Task and Parallel.Invoke). That's OK for few tasks with a run time from 2-5 seconds, but for long running tasks it is better to use a Task object with TaskCreationOptions.LongRunning to run the task in it's own thread. Otherwise the threadpool threads will be blocked for other short running tasks.

Tasks provide a more granular control but that is not required in your case so I would prefer the simpler Parallel.Invoke variant.

\$\endgroup\$
1
  • \$\begingroup\$ Changed my code to this, looks much cleaner and easier to see what is happening. \$\endgroup\$
    – JensB
    Jun 15 '16 at 6:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.