ASP.NET Core中的对象池化技术详解

  using Microsoft.Extensions.DependencyInjection.Extensions;

  using Microsoft.Extensions.ObjectPool;

  using System.Security.Cryptography;

  using System.Text;

  var builder = WebApplication.CreateBuilder(args);

  // DefaultPooledObjectPolicy: 默认的策略,继承抽象类PooledObjectPolicy

  builder.Services.TryAddSingleton();

  builder.Services.TryAddSingleton>(serviceProvider =>

  {

  var provider = serviceProvider.GetRequiredService();

  var policy = new DefaultPooledObjectPolicy();

  return provider.Create(policy);

  });

  builder.Services.TryAddSingleton>(serviceProvider => {

  var provider = serviceProvider.GetRequiredService();

  var policy = new PersonPoolPolicy();

  return provider.Create(policy);

  });

  builder.Services.TryAddSingleton>(serviceProvider =>

  {

  var provider = serviceProvider.GetRequiredService();

  var policy = new StringBuilderPooledObjectPolicy();

  return provider.Create(policy);

  });

  var app = builder.Build();

  // config middleware

  app.UseMiddleware();

  app.MapGet("/", () => "Hello rjcql!");

  // return the SHA256 hash of a word

  http://localhost:5128/hash/xxxx

  app.MapGet("/hash/{word}", (string word, ObjectPool bufferPool) =>

  {

  var buffer = bufferPool.Get();

  try

  {

  // Set the buffer data to the ASCII values of a word

  for (var i = 0; i < word.Length; i++)

  {

  buffer.Data[i] = (byte)word[i];

  }

  Span hash = stackalloc byte[32];

  SHA256.HashData(buffer.Data.AsSpan(0, word.Length), hash);

  return "Hash: " + Convert.ToHexString(hash);

  }

  finally

  {

  // Data is automatically reset because this type implemented IResettable

  bufferPool.Return(buffer);

  }

  });

  app.MapGet("/create/{name}", (string name, ObjectPool personPool) =>

  {

  var person = personPool.Get();

  try

  {

  person.Id = Guid.NewGuid().ToString("N");

  var lastName = person.Name; // 这个是上一个对象的值

  person.Name = name;

  return $"{person.Id}:{person.Name}, {lastName}";

  }

  finally

  {

  // 根据条件回收

  personPool.Return(person);

  }

  });

  app.Run();

  public class ReusableBuffer : IResettable

  {

  public byte[] Data { get; } = new byte[1024 * 1024]; // 1 MB

  public bool TryReset()

  {

  Array.Clear(Data);

  return true;

  }

  }

  public class Person

  {

  public string Id { get; set; }

  public string Name { get; set; }

  }

  public class PersonPoolPolicy : PooledObjectPolicy

  {

  public override Person Create()

  {

  return new Person { Id = "", Name = "rjcql" };

  }

  public override bool Return(Person p)

  {

  if (p.Name != "rjcql")

  {

  // 不允许其他名称的对象放入对象池

  return false;

  }

  return true;

  }

  }

  ///

  /// 创建中间件

  ///

  public class BirthdayMiddleware

  {

  private readonly RequestDelegate _next;

  public BirthdayMiddleware(RequestDelegate next)

  {

  _next = next;

  }

  public async Task InvokeAsync(HttpContext context, ObjectPool builderPool)

  {

  var stringBuilder = builderPool.Get();

  try

  {

  stringBuilder.Append("Hi");

  // 在中间干点啥别的

  // await context.Response.WriteAsync(stringBuilder.ToString());

  await _next.Invoke(context);

  }

  finally // 即使出错也要保证归还对象

  {

  builderPool.Return(stringBuilder);

  }

  }

  }