.NET Core 에서 Object Pool 의 다양한 용법 에 대한 상세 한 설명

7791 단어 .netcoreobjectpool
머리말
복용 은 중요 한 화제 이자 우리 일상 개발 에서 자주 발생 하 는 불가피 한 문제 이다.
가장 간단 하고 여러분 이 가장 잘 아 는 예 를 들 면 데이터베이스 연결 탱크 는 바로 데이터베이스 연결 을 복용 하 는 것 입 니 다.
그럼 복용 의 의 미 는 어디 에 있 을까요?
쉽게 말 하면 불필요 한 자원 손실 을 줄 이 는 것 이다.
데이터베이스 연결 외 에 도 상황 이나 수요 에 따라 재 활용 해 야 할 대상 이 많 을 수 있 으 며,이때 이른바 오 브 젝 트 풀(대상 풀)이 생 긴 다.
젊은이 들 도 비슷 한 기능 을 스스로 실 현 했 거나,ConcurrentBag 을 사용 하거나,ConcurrentQueue 를 사용 하거나,다른 방안 을 사용 해 야 한다.
이것 도 마이크로소프트 문서 에서 의 실현 을 공유 합 니 다.
How to: Create an Object Pool by Using a ConcurrentBag
물론.NET Core 에 서 는 마이크로소프트 가 간단 한 Object Pool 을 실현 하 는 데 도움 을 주 었 다.
Microsoft.Extensions.ObjectPool 의 인용 만 추가 하면 사용 할 수 있 습 니 다.
Microsoft.Extensions.ObjectPool
Microsoft.Extensions.ObjectPool 은.NET Core 의 기본 라 이브 러 리 라 고 할 수 있 습 니 다.
이것 은 aspnet 의 Common 프로젝트 에 위치 하고 있 으 며,유형의 다른 기초 모듈 은 모두 관련 기능 을 사용 하고 있 으 며,마치 Routing 프로젝트 와 같다.
다음은 그것 의 용법 을 간단히 보 겠 습 니 다.
시작 하기 전에 재 활용 가능 한 object 를 정의 합 니 다.

public class Demo
{
 public int Id { get; set; }
 public string Name { get; set; }
 public DateTime CreateTimte { get; set; }
}
용법

var defalutPolicy = new DefaultPooledObjectPolicy<Demo>();
//          = Environment.ProcessorCount * 2
var defaultPool = new DefaultObjectPool<Demo>(defalutPolicy);
for (int i = 0; i < PoolSize; i++)
{
 item1 = defaultPool.Get();
 Console.WriteLine($"#{i+1}-{item1.Id}-{item1.Name}-{item1.CreateTimte}");
}
pool 을 만 들 기 전에 Policy 를 정의 해 야 합 니 다.여 기 는 직접 자체 적 인 Default Pooled Object Policy 로 구성 되 어 있 습 니 다.
대상 풀 에는 유지 보수 의 최대 수량,스 레 드 수가 있 습 니 다.
pool 대상 의 Get 방법 을 통 해 대상 풀 에서 대상 을 꺼 냅 니 다.
위 코드 실행 결과
#1-0--01/01/0001 00:00:00
#2-0--01/01/0001 00:00:00
#3-0--01/01/0001 00:00:00
#4-0--01/01/0001 00:00:00
#5-0--01/01/0001 00:00:00
#6-0--01/01/0001 00:00:00
#7-0--01/01/0001 00:00:00
#8-0--01/01/0001 00:00:00
이 결 과 는 Object Pool 의 대상 이 모두 직접 new 로 나 왔 고 일부 속성 에 대해 평가 절하 작업 을 하지 않 았 으 며 이때 실제 적 인 의미 가 많 지 않다 는 것 을 나타 낸다.
왜냐하면DefaultPooledObjectPolicy원래 새로운 대상 이 나 왔 기 때 문 입 니 다.많은 경우 에 이것 은 우리 가 기대 하 는 것 이 아 닙 니 다!
우리 의 실제 사용 에 부합 하려 면 스스로 Policy 를 정의 해 야 합 니 다!
다음은 사용법 2.
용법
먼저 Policy 를 정의 하여 IPooled Object Policy 라 는 인 터 페 이 스 를 실현 합 니 다.T 는 자 연 스 럽 게 우리 데모 류 야.

public class DemoPooledObjectPolicy : IPooledObjectPolicy<Demo>
{
 public Demo Create()
 {
  return new Demo { Id = 1, Name = "catcher", CreateTimte = DateTime.Now };
 }
 
 public bool Return(Demo obj)
 {
  return true;
 }
}
여기 서 Create 와 Return 두 가지 방법 을 실현 해 야 합 니 다.
명지 의 를 보면 Create 방법 은 Demo 대상 을 만 드 는 데 쓰 이 는 것 이 고 Return 방법 은 Demo 대상 을 Object Pool 에 던 지 는 것 이다.
그리고 Demo Pooled ObjectPolicy 로 Default Pooled ObjectPolicy 를 교체 합 니 다.

var demoPolicy = new DemoPooledObjectPolicy();
var defaultPoolWithDemoPolicy = new DefaultObjectPool<Demo>(demoPolicy,1);
// 
item1 = defaultPoolWithDemoPolicy.Get();
// 
defaultPoolWithDemoPolicy.Return(item1);
// ,    
item2 = defaultPoolWithDemoPolicy.Get();
Console.WriteLine($"{item1.Id}-{item1.Name}-{item1.CreateTimte}");
Console.WriteLine($"{item2.Id}-{item2.Name}-{item2.CreateTimte}");
Console.WriteLine(item1 == item2);
//      
item3 = defaultPoolWithDemoPolicy.Get();
Console.WriteLine($"{item3.Id}-{item3.Name}-{item3.CreateTimte}");
Console.WriteLine(item3 == item1);
대상 풀 을 하나의 대상 만 남 겨 두 는 것 을 정의 합 니 다.
object pool 에서 꺼 낸 후 한 단계 돌려 주 는 작업 이 있 기 때문에 item 1 과 item 2 는 같은 대상 이 어야 합 니 다.
object pool 에서 item 2 를 꺼 낸 후에 돌려 주지 않 았 기 때문에 object pool 은 우리 가 정의 한 Policy 를 바탕 으로 새로운 대상 을 만 들 것 입 니 다.
다음은 용법 2 의 출력 결과 입 니 다:
1-catcher-09/17/2018 22:32:38
1-catcher-09/17/2018 22:32:38
True
1-catcher-09/17/2018 22:32:38
False
item 1,item 2 와 item 3 의 각 속성 이 같 고 item 1 과 item 2 가 같은 대상 임 을 볼 수 있 습 니 다.item 3 과 item 1 은 같 지 않 습 니 다.
용법
Default ObjectPool 외 에 도 Default Object Pool Provider 도 Object Pool 을 만 들 수 있 습 니 다.
Object Pool 을 만 들 면 Policy 를 떠 날 수 없 을 것 입 니 다.그래서 여 기 는 우리 가 정의 한 Demo Pooled Object Policy 를 사 용 했 습 니 다.

var defaultProvider = new DefaultObjectPoolProvider();
var policy = new DemoPooledObjectPolicy();
//default maximumRetained is Environment.ProcessorCount * 2
ObjectPool<Demo> pool = defaultProvider.Create(policy);
item1 = pool.Get();
pool.Return(item1);
item2 = pool.Get();
Console.WriteLine($"{item1.Id}-{item1.Name}-{item1.CreateTimte}");
Console.WriteLine($"{item2.Id}-{item2.Name}-{item2.CreateTimte}");
Console.WriteLine(item1 == item2);
item3 = pool.Get();
Console.WriteLine($"{item3.Id}-{item3.Name}-{item3.CreateTimte}");
Console.WriteLine(item3 == item2);
Provider 로 Object Pool 을 만 들 때 최대 대상 수 를 지정 할 수 없고 기본 Environment.ProcessorCount*2 만 사용 할 수 있 습 니 다.
뒤의 사용 은 용법 2 와 같다.
item 1 과 item 2 가 같은 대상 임 을 볼 수 있 습 니 다.오 브 젝 트 풀 에서 상 대 를 가 져 갈 때 첫 번 째 를 가 져 오기 때문에 돌려 주 고 다시 가 져 가면 원래 의 첫 번 째 를 가 져 옵 니 다.
item 3 는 Object Pool 에서 직접 꺼 냈 습 니 다.다시 만 들 지 않 았 습 니 다.여기 Object Pool 은 용법 2 중 하나 가 아 닌 여러 대상 을 유지 하고 있 기 때문에 Pool 에서 직접 가 져 왔 습 니 다.
다음은 출력 결과 입 니 다.
1-catcher-09/17/2018 22:38:34
1-catcher-09/17/2018 22:38:34
True
1-catcher-09/17/2018 22:38:34
False
용법 2 와 본질 은 같다.
용법
위의 용법 처럼 우리 가 정상적으로 사용 하 는 것 같 지 않다.우 리 는 주입 에 의존 해 야 한다.
그럼 마지막 으로 의존 주입 을 어떻게 결합 하 는 지 살 펴 보 자.물론 이곳 의 본질은 Policy 와 Provider 라 는 두 가 지 를 떠 날 수 없다.

IServiceCollection services = new ServiceCollection();
services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
services.AddSingleton(s =>
{
 var provider = s.GetRequiredService<ObjectPoolProvider>();
 return provider.Create(new DemoPooledObjectPolicy());
});
ServiceProvider serviceProvider = services.BuildServiceProvider();
var pool = serviceProvider.GetService<ObjectPool<Demo>>();
item1 = pool.Get();
pool.Return(item1);
item2 = pool.Get();
Console.WriteLine($"{item1.Id}-{item1.Name}-{item1.CreateTimte}");
Console.WriteLine($"{item2.Id}-{item2.Name}-{item2.CreateTimte}");
Console.WriteLine(item1 == item2);
item3 = pool.Get();
Console.WriteLine($"{item3.Id}-{item3.Name}-{item3.CreateTimte}");
Console.WriteLine(item3 == item2);
우 리 는 먼저 Provider 에 대한 등록 을 마 친 다음 에 인 스 턴 스 를 가지 고 Object Pool 을 만 들 면 됩 니 다.
다른 곳 에서 쓰 려 면 구조 함 수 를 통 해 주입 하면 된다.
이곳 의 결과 도 앞 과 같 아서 더 이상 말 할 것 이 없다.
총결산
이 몇 가지 용법 중에서 우리 가 가장 자주 사용 하 는 것 은 용법 4 이다.
그러나 그런 용법 을 막론하고 우 리 는 Object Pool 은 Pool,Policy,Provider 라 는 세 녀석 을 떠 날 수 없다 는 것 을 알 아야 한다.
이 세 개가 있 으 면 아마도 우 리 는 하고 싶 은 대로 할 수 있 을 것 이다.
물론,그것 은 또 몇 가지 특별한 것 을 제공 하 였 으 니,흥미 있 는 것 은 가서 볼 수 있다.
•LeakTrackingObjectPool
•StringBuilderPooledObjectPolicy
마지막 으로 하나의 뇌 도 로 본문 을 끝 냈 다.

위 에서 말 한 것 은 편집장 님 께 서 소개 해 주신.NET Core 에서 Object Pool 의 다양한 용법 에 대한 상세 한 설명 입 니 다.여러분 께 도움 이 되 셨 으 면 좋 겠 습 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기