Program.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (c) .NET Foundation. All rights reserved.
  2. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  3. using System;
  4. using System.IO;
  5. using System.Reflection;
  6. using System.Runtime;
  7. using System.Threading;
  8. using Benchmarks.Configuration;
  9. using Microsoft.AspNetCore.Hosting;
  10. using Microsoft.Extensions.Configuration;
  11. using Microsoft.Extensions.DependencyInjection;
  12. namespace Benchmarks
  13. {
  14. public class Program
  15. {
  16. public static string[] Args;
  17. public static string Server;
  18. public static void Main(string[] args)
  19. {
  20. Args = args;
  21. Console.WriteLine();
  22. Console.WriteLine("ASP.NET Core Benchmarks");
  23. Console.WriteLine("-----------------------");
  24. Console.WriteLine($"Current directory: {Directory.GetCurrentDirectory()}");
  25. Console.WriteLine($"WebHostBuilder loading from: {typeof(WebHostBuilder).GetTypeInfo().Assembly.Location}");
  26. var config = new ConfigurationBuilder()
  27. .AddCommandLine(args)
  28. .AddEnvironmentVariables(prefix: "ASPNETCORE_")
  29. .AddJsonFile("hosting.json", optional: true)
  30. .Build();
  31. Server = config["server"] ?? "Kestrel";
  32. var webHostBuilder = new WebHostBuilder()
  33. .UseContentRoot(Directory.GetCurrentDirectory())
  34. .UseConfiguration(config)
  35. .UseStartup<Startup>()
  36. .ConfigureServices(services => services
  37. .AddSingleton(new ConsoleArgs(args))
  38. .AddSingleton<IScenariosConfiguration, ConsoleHostScenariosConfiguration>()
  39. .AddSingleton<Scenarios>()
  40. )
  41. .UseDefaultServiceProvider(
  42. (context, options) => options.ValidateScopes = context.HostingEnvironment.IsDevelopment());
  43. if (String.Equals(Server, "Kestrel", StringComparison.OrdinalIgnoreCase))
  44. {
  45. var threads = GetThreadCount(config);
  46. webHostBuilder = webHostBuilder.UseKestrel();
  47. if (threads > 0)
  48. {
  49. webHostBuilder = webHostBuilder.UseLibuv(options => options.ThreadCount = threads);
  50. }
  51. }
  52. else if (String.Equals(Server, "HttpSys", StringComparison.OrdinalIgnoreCase))
  53. {
  54. webHostBuilder = webHostBuilder.UseHttpSys();
  55. }
  56. else
  57. {
  58. throw new InvalidOperationException($"Unknown server value: {Server}");
  59. }
  60. var webHost = webHostBuilder.Build();
  61. Console.WriteLine($"Using server {Server}");
  62. Console.WriteLine($"Server GC is currently {(GCSettings.IsServerGC ? "ENABLED" : "DISABLED")}");
  63. var nonInteractiveValue = config["NonInteractive"];
  64. if (nonInteractiveValue == null || !bool.Parse(nonInteractiveValue))
  65. {
  66. StartInteractiveConsoleThread();
  67. }
  68. webHost.Run();
  69. }
  70. private static void StartInteractiveConsoleThread()
  71. {
  72. // Run the interaction on a separate thread as we don't have Console.KeyAvailable on .NET Core so can't
  73. // do a pre-emptive check before we call Console.ReadKey (which blocks, hard)
  74. var started = new ManualResetEvent(false);
  75. var interactiveThread = new Thread(() =>
  76. {
  77. Console.WriteLine("Press 'C' to force GC or any other key to display GC stats");
  78. Console.WriteLine();
  79. started.Set();
  80. while (true)
  81. {
  82. var key = Console.ReadKey(intercept: true);
  83. if (key.Key == ConsoleKey.C)
  84. {
  85. Console.WriteLine();
  86. Console.Write("Forcing GC...");
  87. GC.Collect();
  88. GC.WaitForPendingFinalizers();
  89. GC.Collect();
  90. Console.WriteLine(" done!");
  91. }
  92. else
  93. {
  94. Console.WriteLine();
  95. Console.WriteLine($"Allocated: {GetAllocatedMemory()}");
  96. Console.WriteLine($"Gen 0: {GC.CollectionCount(0)}, Gen 1: {GC.CollectionCount(1)}, Gen 2: {GC.CollectionCount(2)}");
  97. }
  98. }
  99. })
  100. {
  101. IsBackground = true
  102. };
  103. interactiveThread.Start();
  104. started.WaitOne();
  105. }
  106. private static string GetAllocatedMemory(bool forceFullCollection = false)
  107. {
  108. double bytes = GC.GetTotalMemory(forceFullCollection);
  109. return $"{((bytes / 1024d) / 1024d).ToString("N2")} MB";
  110. }
  111. private static int GetThreadCount(IConfigurationRoot config)
  112. {
  113. var threadCountValue = config["threadCount"];
  114. return threadCountValue == null ? -1 : int.Parse(threadCountValue);
  115. }
  116. }
  117. }