forked from dotnet/efcore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
140 lines (112 loc) · 4.73 KB
/
Program.cs
File metadata and controls
140 lines (112 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace Samples
{
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
}
public class BloggingContext : DbContext
{
public static long InstanceCount;
public BloggingContext(DbContextOptions options)
: base(options)
=> Interlocked.Increment(ref InstanceCount);
public DbSet<Blog> Blogs { get; set; }
}
public class BlogController
{
private readonly BloggingContext _context;
public BlogController(BloggingContext context) => _context = context;
public async Task ActionAsync() => await _context.Blogs.FirstAsync();
}
public class Startup
{
private const string ConnectionString
= @"Server=(localdb)\mssqllocaldb;Database=Demo.ContextPooling;Integrated Security=True;ConnectRetryCount=0";
public void ConfigureServices(IServiceCollection services)
{
// Switch the lines below to compare pooling with the traditional instance-per-request approach.
//services.AddDbContext<BloggingContext>(c => c.UseSqlServer(ConnectionString));
services.AddDbContextPool<BloggingContext>(c => c.UseSqlServer(ConnectionString));
}
}
public class Program
{
private const int Threads = 32;
private const int Seconds = 10;
private static long _requestsProcessed;
private static async Task Main()
{
var serviceCollection = new ServiceCollection();
new Startup().ConfigureServices(serviceCollection);
var serviceProvider = serviceCollection.BuildServiceProvider();
SetupDatabase(serviceProvider);
var stopwatch = new Stopwatch();
MonitorResults(TimeSpan.FromSeconds(Seconds), stopwatch);
await Task.WhenAll(
Enumerable
.Range(0, Threads)
.Select(_ => SimulateRequestsAsync(serviceProvider, stopwatch)));
}
private static void SetupDatabase(IServiceProvider serviceProvider)
{
using (var serviceScope = serviceProvider.CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<BloggingContext>();
if (context.Database.EnsureCreated())
{
context.Blogs.Add(new Blog { Name = "The Dog Blog", Url = "http://sample.com/dogs" });
context.Blogs.Add(new Blog { Name = "The Cat Blog", Url = "http://sample.com/cats" });
context.SaveChanges();
}
}
}
private static async Task SimulateRequestsAsync(IServiceProvider serviceProvider, Stopwatch stopwatch)
{
while (stopwatch.IsRunning)
{
using (var serviceScope = serviceProvider.CreateScope())
{
await new BlogController(serviceScope.ServiceProvider.GetService<BloggingContext>()).ActionAsync();
}
Interlocked.Increment(ref _requestsProcessed);
}
}
private static async void MonitorResults(TimeSpan duration, Stopwatch stopwatch)
{
var lastInstanceCount = 0L;
var lastRequestCount = 0L;
var lastElapsed = TimeSpan.Zero;
stopwatch.Start();
while (stopwatch.Elapsed < duration)
{
await Task.Delay(TimeSpan.FromSeconds(1));
var instanceCount = BloggingContext.InstanceCount;
var requestCount = _requestsProcessed;
var elapsed = stopwatch.Elapsed;
var currentElapsed = elapsed - lastElapsed;
var currentRequests = requestCount - lastRequestCount;
Console.WriteLine(
$"[{DateTime.Now:HH:mm:ss.fff}] "
+ $"Context creations/second: {instanceCount - lastInstanceCount} | "
+ $"Requests/second: {Math.Round(currentRequests / currentElapsed.TotalSeconds)}");
lastInstanceCount = instanceCount;
lastRequestCount = requestCount;
lastElapsed = elapsed;
}
Console.WriteLine();
Console.WriteLine($"Total context creations: {BloggingContext.InstanceCount}");
Console.WriteLine(
$"Requests per second: {Math.Round(_requestsProcessed / stopwatch.Elapsed.TotalSeconds)}");
stopwatch.Stop();
}
}
}