Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Title: Truly simple async/await for synchronous code
- // Author: Emily Heiner
- // Date: 2016-12-15
- // This code is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported license.
- // You are free to share and adapt this code for any purposes, commerical and non-commercial,
- // as long as appropriate credit is given, you indicate if changes were made, and you share your
- // modified code. License details can be found at https://creativecommons.org/licenses/by-sa/3.0/
- void Main()
- {
- // Queues, runs, and waits for the tasks to complete
- QueueAndRunTasks(32);
- Console.WriteLine("Results:");
- // We need to convert the ConcurrentDictionary to a Dictionary to iterate through the items
- foreach (var result in TaskResults.ToDictionary(entry => entry.Key, entry => entry.Value))
- {
- Console.WriteLine("Thread #" + result.Key.ToString() + " slept for " + result.Value.ToString() + "ms");
- }
- Console.WriteLine("Done!");
- }
- // Counts the number of threads
- private static int ThreadCount = 0;
- // Stores the results of the async tasks
- private static ConcurrentDictionary<int, int> TaskResults = new ConcurrentDictionary<int, int>();
- // Random number generator. It is static in order to provide a more random set of numbers
- private static Random RandomGenerator = new Random();
- /// <summary>
- /// Starts a given number of threads and waits for them to complete
- /// </summary>
- /// <param name="numTasks">Number of threads to generate</param>
- public static void QueueAndRunTasks(int numTasks)
- {
- // Holds the tasks that we're going to execute
- var tasks = new List<Task>();
- Console.WriteLine("Adding tasks to queue.");
- // Add i tasks to the queue
- for (int i = 0; i < numTasks; i++)
- {
- // Add the function to the tasks to run
- tasks.Add(ThreadSleepAsync(i));
- }
- Console.WriteLine("Waiting for tasks to complete.");
- // Task.WaitAll() requires an array. Convert the List<Task> to Task[]
- Task.WaitAll(tasks.ToArray());
- Console.WriteLine("Tasks complete!");
- }
- /// <summary>
- /// Function to synchronously sleep a thread asynchronously
- /// </summary>
- /// <param name="threadId">ID number of the thread that is being executed</param>
- /// <returns>The number of ms that the task slept for</returns>
- public static async Task ThreadSleepAsync(int threadId)
- {
- // The meat of the async goodness. Any synchronous code inside of this will run asynchronously
- int result = await Task.Run(() =>
- {
- // Increment the thread counter in a thread safe way. Must be inside of the Task.Run() function at the beginning
- Interlocked.Increment(ref ThreadCount);
- // Generate a number from 1000 to 5000, in increments of 1000
- int sleepTime = (RandomGenerator.Next(0, 5) + 1) * 1000;
- Console.WriteLine("Thread #" + threadId + ", Sleeping for " + sleepTime.ToString() + "ms, Thread Count: " + ThreadCount.ToString());
- // Sleep the thread for the randomly generated time, proving async
- Thread.Sleep(sleepTime);
- // Decrement the thread counter in a thread safe way. Must be inside of the Task.Run() function at the end
- Interlocked.Decrement(ref ThreadCount);
- // Return the amount of time that the thread slept
- return sleepTime;
- }
- );
- // Add the result to the ConcurrentDictionary (thread safe Dictionary)
- TaskResults.TryAdd(threadId, result);
- }
Advertisement
Add Comment
Please, Sign In to add comment