Last active
August 29, 2015 14:08
-
-
Save svick/251f233d856a763fcf16 to your computer and use it in GitHub Desktop.
Proving that the Task dispatching loop doesn't wait for thread scheduling quantum
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Diagnostics; | |
| using System.Threading.Tasks; | |
| class Program | |
| { | |
| private static void Main() | |
| { | |
| MainAsync().Wait(); | |
| } | |
| private static async Task MainAsync() | |
| { | |
| var sw = new Stopwatch(); | |
| sw.Start(); | |
| for (int i = 1; i <= 100; i++) | |
| { | |
| await PreciseTimer.Delay(1); | |
| } | |
| sw.Stop(); | |
| Console.WriteLine(sw.ElapsedMilliseconds); // 103 ms | |
| sw.Restart(); | |
| for (int i = 1; i <= 100; i++) | |
| { | |
| await Task.Delay(1); | |
| } | |
| sw.Stop(); | |
| Console.WriteLine(sw.ElapsedMilliseconds); // 1544 ms | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Threading; | |
| using System.Threading.Tasks; | |
| // this is extremely wasteful, but that doesn't matter here | |
| static class PreciseTimer | |
| { | |
| static PreciseTimer() | |
| { | |
| var thread = new Thread(TimerMethod); | |
| thread.IsBackground = true; | |
| thread.Start(); | |
| } | |
| private static object Lock = new object(); | |
| private static DateTime? FireTime = null; | |
| private static Action Action = null; | |
| private static void TimerMethod() | |
| { | |
| while (true) | |
| { | |
| Action a = null; | |
| lock (Lock) | |
| { | |
| if (FireTime != null && FireTime.Value <= DateTime.Now) | |
| { | |
| a = Action; | |
| FireTime = null; | |
| Action = null; | |
| } | |
| } | |
| if (a != null) | |
| { | |
| a(); | |
| } | |
| } | |
| } | |
| public static Task Delay(int msDelay) | |
| { | |
| var time = DateTime.Now.AddMilliseconds(msDelay); | |
| var tcs = new TaskCompletionSource<bool>(); | |
| lock (Lock) | |
| { | |
| if (FireTime != null) | |
| throw new Exception(); | |
| FireTime = time; | |
| Action = () => tcs.SetResult(true); | |
| } | |
| return tcs.Task; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment