So let's say you have something you want to run in a console application, perhaps something with a few jobs for an application. So simple answer is, write some code in the Program.cs and away you go... Now, let's say you need to do three different things and for performance reasons they can all be done simultaneously and when they all are completed, you want to execute something to know they are all done. There are a lot of ways to do this with DI or with different toolkits, but without the full pop and circumstance, here is a simple method to do this. The only usings you need for this are System; System.Text; System.Threading; and System.Threading.Tasks;.
So the first thing you need to do is create a class to hold the threads along with the function that needs to run for the thread and a completed flag to know when the task is completed. Here is an example below. This one also has some basic logging included so that if one of the functions fail, it can be logged properly.
public class Threadder { private Thread thread; private Action action; private Action runAfterComplete; private Func<Task> func; private ILogger logger; public bool HasCompletedThread { get; private set; } = false; public void ThreadStart() { thread.Start(); } private void Run() { try { action(); } catch (Exception ex) { logger.LogCritical(ex, $"Error processing {action.Method.Name}"); } finally { CompleteThread(); } } private void RunAsync() { try { func().Wait(); } catch (Exception ex) { logger.LogCritical(ex, $"Error processing {func.Method.Name}"); } finally { CompleteThread(); } } private void CompleteThread() { HasCompletedThread = true; runAfterComplete(); } public static Threadder CreateFrom(Action action, Action runAfterComplete) { { action = action, runAfterComplete = runAfterComplete, logger = EmailLogger.CreateFrom() }; return threadder; } public static Threadder CreateFrom(Func<Task> func, Action runAfterComplete) { { func = func, runAfterComplete = runAfterComplete, logger = EmailLogger.CreateFrom() }; return threadder; } }
Then on the Program.cs class create an IEnumerable with the list of functions to be called by implementing Threader.CreateFrom(MethodName,SomeMethodToExcecuteUponCompletionOfAllThreads);
Finally, loop through the IEnumerable of threadders calling ThreadStart(); on each item. This will start each of the threads. The sample method for calling when all threads is completed is below
private static void CallAfterThreadComplete() { ILogger logger = EmailLogger.CreateFrom(); if (threads.All(t => t.HasCompletedThread)) { logger.LogInformation("Closing in 5 seconds"); System.Threading.Thread.Sleep(5000); } }