EmilySamantha80

Truly simple async/await for synchronous code

Dec 15th, 2016
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.29 KB | None | 0 0
  1. // Title:  Truly simple async/await for synchronous code
  2. // Author: Emily Heiner
  3. // Date:   2016-12-15
  4. // This code is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported license.
  5. // You are free to share and adapt this code for any purposes, commerical and non-commercial,
  6. // as long as appropriate credit is given, you indicate if changes were made, and you share your
  7. // modified code. License details can be found at https://creativecommons.org/licenses/by-sa/3.0/
  8.  
  9. void Main()
  10. {
  11.     // Queues, runs, and waits for the tasks to complete
  12.     QueueAndRunTasks(32);
  13.  
  14.     Console.WriteLine("Results:");
  15.     // We need to convert the ConcurrentDictionary to a Dictionary to iterate through the items
  16.     foreach (var result in TaskResults.ToDictionary(entry => entry.Key, entry => entry.Value))
  17.     {
  18.         Console.WriteLine("Thread #" + result.Key.ToString() + " slept for " + result.Value.ToString() + "ms");
  19.     }
  20.    
  21.     Console.WriteLine("Done!");
  22. }
  23.  
  24. // Counts the number of threads
  25. private static int ThreadCount = 0;
  26.  
  27. // Stores the results of the async tasks
  28. private static ConcurrentDictionary<int, int> TaskResults = new ConcurrentDictionary<int, int>();
  29.  
  30. // Random number generator. It is static in order to provide a more random set of numbers
  31. private static Random RandomGenerator = new Random();
  32.  
  33. /// <summary>
  34. /// Starts a given number of threads and waits for them to complete
  35. /// </summary>
  36. /// <param name="numTasks">Number of threads to generate</param>
  37. public static void QueueAndRunTasks(int numTasks)
  38. {
  39.     // Holds the tasks that we're going to execute
  40.     var tasks = new List<Task>();
  41.  
  42.     Console.WriteLine("Adding tasks to queue.");
  43.  
  44.     // Add i tasks to the queue
  45.     for (int i = 0; i < numTasks; i++)
  46.     {
  47.         // Add the function to the tasks to run
  48.         tasks.Add(ThreadSleepAsync(i));
  49.     }
  50.    
  51.     Console.WriteLine("Waiting for tasks to complete.");
  52.    
  53.     // Task.WaitAll() requires an array. Convert the List<Task> to Task[]
  54.     Task.WaitAll(tasks.ToArray());
  55.    
  56.     Console.WriteLine("Tasks complete!");
  57. }
  58.  
  59. /// <summary>
  60. /// Function to synchronously sleep a thread asynchronously
  61. /// </summary>
  62. /// <param name="threadId">ID number of the thread that is being executed</param>
  63. /// <returns>The number of ms that the task slept for</returns>
  64. public static async Task ThreadSleepAsync(int threadId)
  65. {
  66.     // The meat of the async goodness. Any synchronous code inside of this will run asynchronously
  67.     int result = await Task.Run(() =>
  68.     {
  69.         // Increment the thread counter in a thread safe way. Must be inside of the Task.Run() function at the beginning
  70.         Interlocked.Increment(ref ThreadCount);
  71.  
  72.         // Generate a number from 1000 to 5000, in increments of 1000
  73.         int sleepTime = (RandomGenerator.Next(0, 5) + 1) * 1000;
  74.         Console.WriteLine("Thread #" + threadId + ", Sleeping for " + sleepTime.ToString() + "ms, Thread Count: " + ThreadCount.ToString());
  75.        
  76.         // Sleep the thread for the randomly generated time, proving async
  77.         Thread.Sleep(sleepTime);
  78.        
  79.         // Decrement the thread counter in a thread safe way. Must be inside of the Task.Run() function at the end
  80.         Interlocked.Decrement(ref ThreadCount);
  81.        
  82.         // Return the amount of time that the thread slept
  83.         return sleepTime;
  84.     }
  85.     );
  86.    
  87.     // Add the result to the ConcurrentDictionary (thread safe Dictionary)
  88.     TaskResults.TryAdd(threadId, result);  
  89. }
Advertisement
Add Comment
Please, Sign In to add comment