/aspnetcore/performance/performance-best-practices/samples/3.0/Controllers/AsyncFirstController.cs

https://github.com/aspnet/Docs · C# · 136 lines · 114 code · 22 blank · 0 comment · 0 complexity · 3808f2254d679d079f41b410186a06d6 MD5 · raw file

  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc;
  3. using Microsoft.Extensions.Logging;
  4. using System;
  5. using System.Threading.Tasks;
  6. namespace performance_best_practices.Controllers
  7. {
  8. [Route("api/[controller]")]
  9. [ApiController]
  10. #region snippet1
  11. public class AsyncBadSearchController : Controller
  12. {
  13. [HttpGet("/search")]
  14. public async Task<SearchResults> Get(string query)
  15. {
  16. var query1 = SearchAsync(SearchEngine.Google, query);
  17. var query2 = SearchAsync(SearchEngine.Bing, query);
  18. var query3 = SearchAsync(SearchEngine.DuckDuckGo, query);
  19. await Task.WhenAll(query1, query2, query3);
  20. var results1 = await query1;
  21. var results2 = await query2;
  22. var results3 = await query3;
  23. return SearchResults.Combine(results1, results2, results3);
  24. }
  25. private async Task<SearchResults> SearchAsync(SearchEngine engine, string query)
  26. {
  27. var searchResults = _searchService.Empty();
  28. try
  29. {
  30. _logger.LogInformation("Starting search query from {path}.",
  31. HttpContext.Request.Path);
  32. searchResults = _searchService.Search(engine, query);
  33. _logger.LogInformation("Finishing search query from {path}.",
  34. HttpContext.Request.Path);
  35. }
  36. catch (Exception ex)
  37. {
  38. _logger.LogError(ex, "Failed query from {path}",
  39. HttpContext.Request.Path);
  40. }
  41. return await searchResults;
  42. }
  43. #endregion
  44. private readonly ILogger<AsyncBadSearchController> _logger;
  45. public readonly SearchService _searchService;
  46. public AsyncBadSearchController(ILogger<AsyncBadSearchController> logger,
  47. SearchService searchService)
  48. {
  49. _logger = logger;
  50. _searchService = searchService;
  51. }
  52. }
  53. #region snippet2
  54. public class AsyncGoodSearchController : Controller
  55. {
  56. [HttpGet("/search")]
  57. public async Task<SearchResults> Get(string query)
  58. {
  59. string path = HttpContext.Request.Path;
  60. var query1 = SearchAsync(SearchEngine.Google, query,
  61. path);
  62. var query2 = SearchAsync(SearchEngine.Bing, query, path);
  63. var query3 = SearchAsync(SearchEngine.DuckDuckGo, query, path);
  64. await Task.WhenAll(query1, query2, query3);
  65. var results1 = await query1;
  66. var results2 = await query2;
  67. var results3 = await query3;
  68. return SearchResults.Combine(results1, results2, results3);
  69. }
  70. private async Task<SearchResults> SearchAsync(SearchEngine engine, string query,
  71. string path)
  72. {
  73. var searchResults = _searchService.Empty();
  74. try
  75. {
  76. _logger.LogInformation("Starting search query from {path}.",
  77. path);
  78. searchResults = await _searchService.SearchAsync(engine, query);
  79. _logger.LogInformation("Finishing search query from {path}.", path);
  80. }
  81. catch (Exception ex)
  82. {
  83. _logger.LogError(ex, "Failed query from {path}", path);
  84. }
  85. return await searchResults;
  86. }
  87. #endregion
  88. private readonly ILogger<AsyncGoodSearchController> _logger;
  89. public readonly SearchService _searchService;
  90. public AsyncGoodSearchController(ILogger<AsyncGoodSearchController> logger,
  91. SearchService searchService)
  92. {
  93. _logger = logger;
  94. _searchService = searchService;
  95. }
  96. }
  97. public class SearchEngine
  98. {
  99. public static SearchEngine Bing { get; internal set; }
  100. public static SearchEngine Google { get; internal set; }
  101. public static SearchEngine DuckDuckGo { get; internal set; }
  102. }
  103. public class SearchResults
  104. {
  105. internal static SearchResults Combine(SearchResults results1, SearchResults results2, SearchResults results3)
  106. {
  107. throw new NotImplementedException();
  108. }
  109. public static implicit operator Task<object>(SearchResults v)
  110. {
  111. throw new NotImplementedException();
  112. }
  113. }
  114. }