Is a DbContext per thread in Parallel.ForEach safe?

c# entity-framework entity-framework-6 multithreading parallel-processing

Accepted Answer

ZZZ_tmp
1
9/5/2019 2:50:29 AM

Popular Answer

First Problem: Memory Allocation

Each iteration will produce an instance ofDbContext This will result in the allocation of RAM. Those allocations must be handled by the garbage collector. The performance of the program will suffer if memory is always under demand.

Second problem: SQL overload

Based on the information provided here, you will contactSaveChanges() that is likely to contact a database. If the database call is or will be resource-intensive, the database's performance may suffer.

Third problem: thread blocking

SaveChanges() synchronously stops the thread from progressing. When a database call is made and it takes a long time, the thread will just wait. Likewise for calls to third-party APIs. There won't be any or little performance improvement.

Fourth-issue Parallel For* techniques' parallel execution is not guaranteed.

It is important to keep in mind that individual iterations in a Parallel.For, Parallel.ForEach or ForAll loop may but do not have to execute in parallel.

This seems to be self explanatory.

PLINQ Potential Pitfalls

Understanding PLINQ's Speedup


Reading the comments below the question and Eric J.'s response, I'm afraid the problem's approach is flawed and parallelism won't be of much use.

Thanks for the answer Eric. Keeping in mind that, right now anyway, that we are talking about 100's of ids in that code above where most id's represent work that does not end up in any changes to the database and are short lived while a hand full can take minutes to complete and ultimately add 10's of new records to the DB. What MaxDegreesOfParallelism value would you recommend off the top of your head?

Ahh - yes I should have included that detail. In this instance the task being performed is very much IO bound calling out to third party web API to collect required information for processing. Once all the data is collected, it is processed and may result in some new records needing to be added to the database. There are a few queries to collect some additional information during the processing phase, but all those are performing fine.

The issue, if I am not entirely mistaken, is synchronous calls to third-party APIs that stall the thread.

Here, I believe an async approach to data collection from third-party APIs may be helpful.

It would also be beneficial to avoid allocating heap RAM if possible. At the conclusion of execution, you may save modifications with simply oneDbContext simply one database call per instance.


UPDATE

Eric J. implemented a test to ensure that concurrent execution is working and that threads are not blocking one another, which they are not. The original code he supplied in his response is shown below.

class SomeTaskProcessor
{
    static Random rng = new Random();
    public int Id { get; private set; }
    public SomeTaskProcessor(int id) { Id = id; }
    public void ExecuteLongRunningProcessThatReadsDbAndCreatesSomeNewRecords()
    {
        Console.WriteLine($"Starting ID {Id}");
        System.Threading.Thread.Sleep(rng.Next(1000));
        Console.WriteLine($"Completing ID {Id}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        int[] ids = Enumerable.Range(1, 100).ToArray();

        Parallel.ForEach(ids, id => {
                var processor = new SomeTaskProcessor(id);
                processor.ExecuteLongRunningProcessThatReadsDbAndCreatesSomeNewRecords();
        });
    }
}

I ran similar experiments. I built a server to replicate internet IO with a one-second delay in response. The API server was launched and the first request was sent before each test run. In release configuration, tests were executed.

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase {
    // GET api/values
    [HttpGet]
    public async Task<ActionResult<IEnumerable<string>>> Get() {
        await Task.Delay(1000);

        return new string[] { "value1", "value2" };
    }
}

His code has been changed to contact an API endpoint. It spun five threads and took an average of 23 seconds to execute on my virtual system.

class SomeTaskProcessor {
    private HttpClient http = new HttpClient() {
        BaseAddress = new Uri("http://localhost:49890/api/values")
    };

    public int Id { get; private set; }
    public SomeTaskProcessor(int id) { Id = id; }
    public void ExecuteLongRunningProcessThatReadsDbAndCreatesSomeNewRecords() {
        Console.WriteLine($"Starting ID {Id}. Thread Id: {Thread.CurrentThread.ManagedThreadId}");
        var response = http.GetAsync(String.Empty).GetAwaiter().GetResult();
        Console.WriteLine($"Completing ID {Id}. Response status code is {response.StatusCode}. Thread Id: {Thread.CurrentThread.ManagedThreadId}");
    }
}

class Program {
    static void Main(string[] args) {
        int[] ids = Enumerable.Range(1, 100).ToArray();;

        var stopwatch = new Stopwatch();

        stopwatch.Start();

        Parallel.ForEach(ids, id => {
            var processor = new SomeTaskProcessor(id);
            processor.ExecuteLongRunningProcessThatReadsDbAndCreatesSomeNewRecords();
        });

        // ~23 seconds

        stopwatch.Stop();

        Console.WriteLine(stopwatch.Elapsed.ToString());
    }
}

Terminal output:

Starting ID 51. Thread Id: 4
Starting ID 1. Thread Id: 1
Starting ID 2. Thread Id: 5
Starting ID 52. Thread Id: 9
Starting ID 3. Thread Id: 12
Completing ID 51. Response status code is OK. Thread Id: 4
Starting ID 53. Thread Id: 4
Completing ID 2. Response status code is OK. Thread Id: 5
Starting ID 4. Thread Id: 5
Starting ID 55. Thread Id: 14
Starting ID 6. Thread Id: 15
Completing ID 52. Response status code is OK. Thread Id: 9
Starting ID 56. Thread Id: 9
Completing ID 1. Response status code is OK. Thread Id: 1
Starting ID 7. Thread Id: 1
Completing ID 3. Response status code is OK. Thread Id: 12
Starting ID 9. Thread Id: 12
Starting ID 58. Thread Id: 16
Completing ID 53. Response status code is OK. Thread Id: 4
Starting ID 54. Thread Id: 4
Completing ID 4. Response status code is OK. Thread Id: 5
Starting ID 5. Thread Id: 5
Starting ID 11. Thread Id: 18
Completing ID 55. Response status code is OK. Thread Id: 14
Starting ID 59. Thread Id: 14
Starting ID 61. Thread Id: 20
Completing ID 56. Response status code is OK. Thread Id: 9
Starting ID 57. Thread Id: 9
Completing ID 7. Response status code is OK. Thread Id: 1
Starting ID 8. Thread Id: 1
Completing ID 9. Response status code is OK. Thread Id: 12
Starting ID 10. Thread Id: 12
Completing ID 6. Response status code is OK. Thread Id: 15
Starting ID 12. Thread Id: 15
Starting ID 14. Thread Id: 22
Completing ID 5. Response status code is OK. Thread Id: 5
Starting ID 15. Thread Id: 5
Completing ID 54. Response status code is OK. Thread Id: 4
Starting ID 62. Thread Id: 4
Completing ID 58. Response status code is OK. Thread Id: 16
Starting ID 66. Thread Id: 16
Starting ID 68. Thread Id: 23
Completing ID 11. Response status code is OK. Thread Id: 18
Starting ID 19. Thread Id: 18
Completing ID 59. Response status code is OK. Thread Id: 14
Starting ID 60. Thread Id: 14
Starting ID 21. Thread Id: 24
Completing ID 57. Response status code is OK. Thread Id: 9
Starting ID 69. Thread Id: 9
Completing ID 12. Response status code is OK. Thread Id: 15
Starting ID 13. Thread Id: 15
Completing ID 61. Response status code is OK. Thread Id: 20
Starting ID 73. Thread Id: 20
Completing ID 10. Response status code is OK. Thread Id: 12
Completing ID 8. Response status code is OK. Thread Id: 1
Starting ID 22. Thread Id: 12
Starting ID 26. Thread Id: 1
Starting ID 75. Thread Id: 25
Completing ID 15. Response status code is OK. Thread Id: 5
Starting ID 16. Thread Id: 5
Completing ID 62. Response status code is OK. Thread Id: 4
Starting ID 63. Thread Id: 4
Completing ID 66. Response status code is OK. Thread Id: 16
Starting ID 67. Thread Id: 16
Completing ID 14. Response status code is OK. Thread Id: 22
Starting ID 30. Thread Id: 22
Starting ID 32. Thread Id: 26
Starting ID 76. Thread Id: 27
Completing ID 60. Response status code is OK. Thread Id: 14
Starting ID 77. Thread Id: 14
Completing ID 19. Response status code is OK. Thread Id: 18
Starting ID 20. Thread Id: 18
Completing ID 69. Response status code is OK. Thread Id: 9
Starting ID 70. Thread Id: 9
Completing ID 21. Response status code is OK. Thread Id: 24
Starting ID 33. Thread Id: 24
Completing ID 13. Response status code is OK. Thread Id: 15
Starting ID 35. Thread Id: 15
Completing ID 73. Response status code is OK. Thread Id: 20
Starting ID 74. Thread Id: 20
Completing ID 22. Response status code is OK. Thread Id: 12
Starting ID 23. Thread Id: 12
Completing ID 26. Response status code is OK. Thread Id: 1
Starting ID 27. Thread Id: 1
Completing ID 68. Response status code is OK. Thread Id: 23
Starting ID 81. Thread Id: 23
Starting ID 39. Thread Id: 29
Completing ID 67. Response status code is OK. Thread Id: 16
Starting ID 83. Thread Id: 16
Completing ID 75. Response status code is OK. Thread Id: 25
Completing ID 30. Response status code is OK. Thread Id: 22
Starting ID 31. Thread Id: 22
Completing ID 16. Response status code is OK. Thread Id: 5
Starting ID 87. Thread Id: 25
Starting ID 17. Thread Id: 5
Completing ID 63. Response status code is OK. Thread Id: 4
Starting ID 64. Thread Id: 4
Starting ID 89. Thread Id: 30
Completing ID 76. Response status code is OK. Thread Id: 27
Starting ID 90. Thread Id: 27
Completing ID 32. Response status code is OK. Thread Id: 26
Starting ID 40. Thread Id: 26
Completing ID 77. Response status code is OK. Thread Id: 14
Starting ID 78. Thread Id: 14
Starting ID 42. Thread Id: 31
Completing ID 70. Response status code is OK. Thread Id: 9
Starting ID 71. Thread Id: 9
Completing ID 27. Response status code is OK. Thread Id: 1
Starting ID 28. Thread Id: 1
Completing ID 74. Response status code is OK. Thread Id: 20
Starting ID 92. Thread Id: 20
Completing ID 35. Response status code is OK. Thread Id: 15
Starting ID 36. Thread Id: 15
Completing ID 81. Response status code is OK. Thread Id: 23
Starting ID 82. Thread Id: 23
Completing ID 33. Response status code is OK. Thread Id: 24
Starting ID 34. Thread Id: 24
Completing ID 20. Response status code is OK. Thread Id: 18
Starting ID 43. Thread Id: 18
Completing ID 23. Response status code is OK. Thread Id: 12
Starting ID 24. Thread Id: 12
Starting ID 96. Thread Id: 32
Completing ID 39. Response status code is OK. Thread Id: 29
Completing ID 17. Response status code is OK. Thread Id: 5
Starting ID 18. Thread Id: 5
Starting ID 47. Thread Id: 29
Completing ID 64. Response status code is OK. Thread Id: 4
Starting ID 65. Thread Id: 4
Completing ID 87. Response status code is OK. Thread Id: 25
Starting ID 88. Thread Id: 25
Completing ID 31. Response status code is OK. Thread Id: 22
Completing ID 83. Response status code is OK. Thread Id: 16
Starting ID 84. Thread Id: 16
Starting ID 49. Thread Id: 22
Starting ID 97. Thread Id: 33
Completing ID 90. Response status code is OK. Thread Id: 27
Starting ID 91. Thread Id: 27
Completing ID 40. Response status code is OK. Thread Id: 26
Starting ID 41. Thread Id: 26
Completing ID 89. Response status code is OK. Thread Id: 30
Starting ID 98. Thread Id: 30
Completing ID 78. Response status code is OK. Thread Id: 14
Starting ID 79. Thread Id: 14
Starting ID 100. Thread Id: 34
Completing ID 36. Response status code is OK. Thread Id: 15
Starting ID 37. Thread Id: 15
Completing ID 92. Response status code is OK. Thread Id: 20
Starting ID 93. Thread Id: 20
Completing ID 42. Response status code is OK. Thread Id: 31
Completing ID 28. Response status code is OK. Thread Id: 1
Starting ID 29. Thread Id: 1
Completing ID 24. Response status code is OK. Thread Id: 12
Starting ID 25. Thread Id: 12
Completing ID 82. Response status code is OK. Thread Id: 23
Completing ID 71. Response status code is OK. Thread Id: 9
Starting ID 72. Thread Id: 9
Completing ID 43. Response status code is OK. Thread Id: 18
Starting ID 44. Thread Id: 18
Completing ID 96. Response status code is OK. Thread Id: 32
Completing ID 65. Response status code is OK. Thread Id: 4
Completing ID 88. Response status code is OK. Thread Id: 25
Completing ID 49. Response status code is OK. Thread Id: 22
Starting ID 50. Thread Id: 22
Completing ID 47. Response status code is OK. Thread Id: 29
Starting ID 48. Thread Id: 29
Completing ID 18. Response status code is OK. Thread Id: 5
Completing ID 34. Response status code is OK. Thread Id: 24
Completing ID 84. Response status code is OK. Thread Id: 16
Starting ID 85. Thread Id: 16
Completing ID 97. Response status code is OK. Thread Id: 33
Completing ID 41. Response status code is OK. Thread Id: 26
Completing ID 79. Response status code is OK. Thread Id: 14
Starting ID 80. Thread Id: 14
Completing ID 100. Response status code is OK. Thread Id: 34
Completing ID 93. Response status code is OK. Thread Id: 20
Starting ID 94. Thread Id: 20
Completing ID 29. Response status code is OK. Thread Id: 1
Completing ID 98. Response status code is OK. Thread Id: 30
Starting ID 99. Thread Id: 30
Completing ID 44. Response status code is OK. Thread Id: 18
Starting ID 45. Thread Id: 18
Completing ID 25. Response status code is OK. Thread Id: 12
Completing ID 37. Response status code is OK. Thread Id: 15
Starting ID 38. Thread Id: 15
Completing ID 72. Response status code is OK. Thread Id: 9
Completing ID 91. Response status code is OK. Thread Id: 27
Completing ID 50. Response status code is OK. Thread Id: 22
Completing ID 48. Response status code is OK. Thread Id: 29
Completing ID 85. Response status code is OK. Thread Id: 16
Starting ID 86. Thread Id: 16
Completing ID 80. Response status code is OK. Thread Id: 14
Completing ID 94. Response status code is OK. Thread Id: 20
Starting ID 95. Thread Id: 20
Completing ID 99. Response status code is OK. Thread Id: 30
Completing ID 45. Response status code is OK. Thread Id: 18
Starting ID 46. Thread Id: 18
Completing ID 38. Response status code is OK. Thread Id: 15
Completing ID 86. Response status code is OK. Thread Id: 16
Completing ID 95. Response status code is OK. Thread Id: 20
Completing ID 46. Response status code is OK. Thread Id: 18
00:00:23.6046580

C:\Program Files\dotnet\dotnet.exe (process 7208) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .

The identical code was then converted into an async version. Execution typically takes 7 seconds.

class SomeTaskProcessor {
    private HttpClient http = new HttpClient() {
        BaseAddress = new Uri("http://localhost:49890/api/values")
    };

    public int Id { get; private set; }
    public SomeTaskProcessor(int id) { Id = id; }
    public async Task ExecuteLongRunningProcessThatReadsDbAndCreatesSomeNewRecords() {
        Console.WriteLine($"Starting ID {Id}");
        var response = await http.GetAsync(String.Empty);
        Console.WriteLine($"Completing ID {Id}. Response status code is {response.StatusCode}");
    }
}

class Program {
    static async Task Main(string[] args) {
        int[] ids = Enumerable.Range(1, 100).ToArray();;

        var stopwatch = new Stopwatch();

        stopwatch.Start();

        var tasks = ids.Select(id => {
            var processor = new SomeTaskProcessor(id);
            return processor.ExecuteLongRunningProcessThatReadsDbAndCreatesSomeNewRecords();
        }).ToArray();

        await Task.WhenAll(tasks);

        // ~8 seconds

        stopwatch.Stop();

        Console.WriteLine(stopwatch.Elapsed.ToString());
    }
}

Terminal output:

Starting ID 1. Thread Id: 1
Starting ID 2. Thread Id: 1
Starting ID 3. Thread Id: 1
Starting ID 4. Thread Id: 1
Starting ID 5. Thread Id: 1
Starting ID 6. Thread Id: 1
Starting ID 7. Thread Id: 1
Starting ID 8. Thread Id: 1
Starting ID 9. Thread Id: 1
Starting ID 10. Thread Id: 1
Starting ID 11. Thread Id: 1
Starting ID 12. Thread Id: 1
Starting ID 13. Thread Id: 1
Starting ID 14. Thread Id: 1
Starting ID 15. Thread Id: 1
Starting ID 16. Thread Id: 1
Starting ID 17. Thread Id: 1
Starting ID 18. Thread Id: 1
Starting ID 19. Thread Id: 1
Starting ID 20. Thread Id: 1
Starting ID 21. Thread Id: 1
Starting ID 22. Thread Id: 1
Starting ID 23. Thread Id: 1
Starting ID 24. Thread Id: 1
Starting ID 25. Thread Id: 1
Starting ID 26. Thread Id: 1
Starting ID 27. Thread Id: 1
Starting ID 28. Thread Id: 1
Starting ID 29. Thread Id: 1
Starting ID 30. Thread Id: 1
Starting ID 31. Thread Id: 1
Starting ID 32. Thread Id: 1
Starting ID 33. Thread Id: 1
Starting ID 34. Thread Id: 1
Starting ID 35. Thread Id: 1
Starting ID 36. Thread Id: 1
Starting ID 37. Thread Id: 1
Starting ID 38. Thread Id: 1
Starting ID 39. Thread Id: 1
Starting ID 40. Thread Id: 1
Starting ID 41. Thread Id: 1
Starting ID 42. Thread Id: 1
Starting ID 43. Thread Id: 1
Starting ID 44. Thread Id: 1
Starting ID 45. Thread Id: 1
Starting ID 46. Thread Id: 1
Starting ID 47. Thread Id: 1
Starting ID 48. Thread Id: 1
Starting ID 49. Thread Id: 1
Starting ID 50. Thread Id: 1
Starting ID 51. Thread Id: 1
Starting ID 52. Thread Id: 1
Starting ID 53. Thread Id: 1
Starting ID 54. Thread Id: 1
Starting ID 55. Thread Id: 1
Starting ID 56. Thread Id: 1
Starting ID 57. Thread Id: 1
Starting ID 58. Thread Id: 1
Starting ID 59. Thread Id: 1
Starting ID 60. Thread Id: 1
Starting ID 61. Thread Id: 1
Starting ID 62. Thread Id: 1
Starting ID 63. Thread Id: 1
Starting ID 64. Thread Id: 1
Starting ID 65. Thread Id: 1
Starting ID 66. Thread Id: 1
Starting ID 67. Thread Id: 1
Starting ID 68. Thread Id: 1
Starting ID 69. Thread Id: 1
Starting ID 70. Thread Id: 1
Starting ID 71. Thread Id: 1
Starting ID 72. Thread Id: 1
Starting ID 73. Thread Id: 1
Starting ID 74. Thread Id: 1
Starting ID 75. Thread Id: 1
Starting ID 76. Thread Id: 1
Starting ID 77. Thread Id: 1
Starting ID 78. Thread Id: 1
Starting ID 79. Thread Id: 1
Starting ID 80. Thread Id: 1
Starting ID 81. Thread Id: 1
Starting ID 82. Thread Id: 1
Starting ID 83. Thread Id: 1
Starting ID 84. Thread Id: 1
Starting ID 85. Thread Id: 1
Starting ID 86. Thread Id: 1
Starting ID 87. Thread Id: 1
Starting ID 88. Thread Id: 1
Starting ID 89. Thread Id: 1
Starting ID 90. Thread Id: 1
Starting ID 91. Thread Id: 1
Starting ID 92. Thread Id: 1
Starting ID 93. Thread Id: 1
Starting ID 94. Thread Id: 1
Starting ID 95. Thread Id: 1
Starting ID 96. Thread Id: 1
Starting ID 97. Thread Id: 1
Starting ID 98. Thread Id: 1
Starting ID 99. Thread Id: 1
Starting ID 100. Thread Id: 1
Completing ID 3. Response status code is OK. Thread Id: 14
Completing ID 10. Response status code is OK. Thread Id: 8
Completing ID 8. Response status code is OK. Thread Id: 9
Completing ID 7. Response status code is OK. Thread Id: 15
Completing ID 11. Response status code is OK. Thread Id: 14
Completing ID 4. Response status code is OK. Thread Id: 8
Completing ID 9. Response status code is OK. Thread Id: 9
Completing ID 12. Response status code is OK. Thread Id: 8
Completing ID 13. Response status code is OK. Thread Id: 8
Completing ID 6. Response status code is OK. Thread Id: 8
Completing ID 17. Response status code is OK. Thread Id: 8
Completing ID 18. Response status code is OK. Thread Id: 8
Completing ID 21. Response status code is OK. Thread Id: 8
Completing ID 24. Response status code is OK. Thread Id: 8
Completing ID 20. Response status code is OK. Thread Id: 8
Completing ID 30. Response status code is OK. Thread Id: 8
Completing ID 22. Response status code is OK. Thread Id: 8
Completing ID 34. Response status code is OK. Thread Id: 8
Completing ID 32. Response status code is OK. Thread Id: 9
Completing ID 33. Response status code is OK. Thread Id: 9
Completing ID 39. Response status code is OK. Thread Id: 9
Completing ID 35. Response status code is OK. Thread Id: 8
Completing ID 2. Response status code is OK. Thread Id: 9
Completing ID 44. Response status code is OK. Thread Id: 9
Completing ID 23. Response status code is OK. Thread Id: 8
Completing ID 31. Response status code is OK. Thread Id: 14
Completing ID 38. Response status code is OK. Thread Id: 14
Completing ID 43. Response status code is OK. Thread Id: 8
Completing ID 50. Response status code is OK. Thread Id: 9
Completing ID 1. Response status code is OK. Thread Id: 15
Completing ID 48. Response status code is OK. Thread Id: 14
Completing ID 27. Response status code is OK. Thread Id: 8
Completing ID 49. Response status code is OK. Thread Id: 9
Completing ID 28. Response status code is OK. Thread Id: 15
Completing ID 14. Response status code is OK. Thread Id: 14
Completing ID 29. Response status code is OK. Thread Id: 8
Completing ID 26. Response status code is OK. Thread Id: 14
Completing ID 15. Response status code is OK. Thread Id: 9
Completing ID 19. Response status code is OK. Thread Id: 8
Completing ID 25. Response status code is OK. Thread Id: 15
Completing ID 5. Response status code is OK. Thread Id: 14
Completing ID 40. Response status code is OK. Thread Id: 9
Completing ID 60. Response status code is OK. Thread Id: 8
Completing ID 37. Response status code is OK. Thread Id: 15
Completing ID 41. Response status code is OK. Thread Id: 14
Completing ID 16. Response status code is OK. Thread Id: 9
Completing ID 63. Response status code is OK. Thread Id: 14
Completing ID 36. Response status code is OK. Thread Id: 14
Completing ID 42. Response status code is OK. Thread Id: 9
Completing ID 45. Response status code is OK. Thread Id: 14
Completing ID 64. Response status code is OK. Thread Id: 14
Completing ID 53. Response status code is OK. Thread Id: 9
Completing ID 61. Response status code is OK. Thread Id: 15
Completing ID 52. Response status code is OK. Thread Id: 14
Completing ID 67. Response status code is OK. Thread Id: 14
Completing ID 74. Response status code is OK. Thread Id: 14
Completing ID 75. Response status code is OK. Thread Id: 14
Completing ID 62. Response status code is OK. Thread Id: 15
Completing ID 78. Response status code is OK. Thread Id: 8
Completing ID 66. Response status code is OK. Thread Id: 15
Completing ID 55. Response status code is OK. Thread Id: 14
Completing ID 83. Response status code is OK. Thread Id: 15
Completing ID 59. Response status code is OK. Thread Id: 14
Completing ID 68. Response status code is OK. Thread Id: 8
Completing ID 85. Response status code is OK. Thread Id: 15
Completing ID 47. Response status code is OK. Thread Id: 9
Completing ID 72. Response status code is OK. Thread Id: 14
Completing ID 65. Response status code is OK. Thread Id: 8
Completing ID 84. Response status code is OK. Thread Id: 8
Completing ID 70. Response status code is OK. Thread Id: 14
Completing ID 87. Response status code is OK. Thread Id: 14
Completing ID 56. Response status code is OK. Thread Id: 8
Completing ID 90. Response status code is OK. Thread Id: 15
Completing ID 76. Response status code is OK. Thread Id: 9
Completing ID 73. Response status code is OK. Thread Id: 14
Completing ID 69. Response status code is OK. Thread Id: 8
Completing ID 86. Response status code is OK. Thread Id: 15
Completing ID 81. Response status code is OK. Thread Id: 9
Completing ID 91. Response status code is OK. Thread Id: 15
Completing ID 77. Response status code is OK. Thread Id: 9
Completing ID 57. Response status code is OK. Thread Id: 15
Completing ID 98. Response status code is OK. Thread Id: 9
Completing ID 100. Response status code is OK. Thread Id: 15
Completing ID 79. Response status code is OK. Thread Id: 9
Completing ID 58. Response status code is OK. Thread Id: 15
Completing ID 80. Response status code is OK. Thread Id: 8
Completing ID 82. Response status code is OK. Thread Id: 14
Completing ID 89. Response status code is OK. Thread Id: 9
Completing ID 88. Response status code is OK. Thread Id: 15
Completing ID 97. Response status code is OK. Thread Id: 8
Completing ID 51. Response status code is OK. Thread Id: 14
Completing ID 94. Response status code is OK. Thread Id: 9
Completing ID 93. Response status code is OK. Thread Id: 15
Completing ID 71. Response status code is OK. Thread Id: 8
Completing ID 46. Response status code is OK. Thread Id: 14
Completing ID 54. Response status code is OK. Thread Id: 9
Completing ID 95. Response status code is OK. Thread Id: 15
Completing ID 92. Response status code is OK. Thread Id: 8
Completing ID 99. Response status code is OK. Thread Id: 14
Completing ID 96. Response status code is OK. Thread Id: 9
00:00:06.7737961

C:\Program Files\dotnet\dotnet.exe (process 296) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .

I think the difference between 23 and 7 seconds is sufficient evidence that the situation is an async/await one.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow