728x90
반응형
728x170
▶ ResourcePool.cs
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
namespace TestProject
{
/// <summary>
/// 리소스 풀
/// </summary>
/// <typeparam name="TResource">리소스 타입</typeparam>
public class ResourcePool<TResource>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 병렬 백
/// </summary>
private readonly ConcurrentBag<TResource> concurrentBag = new ConcurrentBag<TResource>();
/// <summary>
/// 수동 리셋 이벤트
/// </summary>
private ManualResetEvent manualResetEvent = new ManualResetEvent(true);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - ResourcePool(resourceList)
/// <summary>
/// 생성자
/// </summary>
/// <param name="resourceList">리소스 리스트</param>
public ResourcePool(List<TResource> resourceList)
{
var enumerator = resourceList.GetEnumerator();
while(enumerator.MoveNext())
{
this.concurrentBag.Add(enumerator.Current);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 구하기 - Get()
/// <summary>
/// 구하기
/// </summary>
/// <returns>리소스</returns>
public TResource Get()
{
TResource resource;
do
{
if(this.concurrentBag.IsEmpty)
{
this.manualResetEvent.Reset();
this.manualResetEvent.WaitOne();
}
}
while(!this.concurrentBag.TryTake(out resource));
return resource;
}
#endregion
#region 해제하기 - Release(resource)
/// <summary>
/// 해제하기
/// </summary>
/// <param name="resource">리소스</param>
public void Release(TResource resource)
{
this.concurrentBag.Add(resource);
this.manualResetEvent.Set();
}
#endregion
}
}
728x90
▶ Resource.cs
namespace TestProject
{
/// <summary>
/// 리소스
/// </summary>
public class Resource
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 카운트
/// </summary>
private int count = 0;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region ID - ID
/// <summary>
/// ID
/// </summary>
public int ID { get; set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - Resource(id)
/// <summary>
/// 생성자
/// </summary>
/// <param name="id">ID</param>
public Resource(int id)
{
ID = id;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 카운트 증가시키기 - IncreasegCount()
/// <summary>
/// 카운트 증가시키기
/// </summary>
public void IncreasegCount()
{
this.count++;
}
#endregion
#region 문자열 구하기 - ToString()
/// <summary>
/// 문자열 구하기
/// </summary>
/// <returns>문자열</returns>
public override string ToString()
{
return $"ID : {ID}, Count : {this.count}";
}
#endregion
}
}
300x250
▶ Program.cs
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace TestProject
{
/// <summary>
/// 프로그램
/// </summary>
class Program
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 프로그램 시작하기 - Main()
/// <summary>
/// 프로그램 시작하기
/// </summary>
private static void Main()
{
List<Resource> resourceList = new List<Resource>()
{
new Resource(0),
new Resource(1),
new Resource(2),
new Resource(3)
};
ResourcePool<Resource> resourcePool = new ResourcePool<Resource>(resourceList);
Parallel.For
(
1,
50,
new ParallelOptions { MaxDegreeOfParallelism = 8 },
(int index) => {
Resource resource = resourcePool.Get();
resource.IncreasegCount();
Console.WriteLine($"[스레드 인덱스 : {index}] {resource.ToString()}");
Thread.Sleep(new Random().Next(600, 3000));
resourcePool.Release(resource);
}
);
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON] 카카오 API를 사용해 키워드 장소 검색하기 (0) | 2021.05.23 |
---|---|
[C#/COMMON] UWP 프로세스/윈도우 리스트 구하기 (0) | 2021.05.23 |
[C#/COMMON] ZipArchive 클래스 : ZIP 파일 생성하기/추출하기 (기능 개선) (0) | 2021.05.21 |
[C#/COMMON] 이미지 파일을 WebP 이미지 파일로 저장하기 (0) | 2021.05.17 |
[C#/COMMON] Thread 클래스 : 특정 사용자 권한으로 스레드 실행하기 (0) | 2021.05.14 |
[C#/COMMON] Visual Studio 확장 개발하기 (0) | 2021.05.13 |
[C#/COMMON] Process 클래스 : UWP 프로세스 여부 구하기 (0) | 2021.05.13 |
[C#/COMMON] 스푸핑(spoofing) 기법을 사용해 시스템 권한으로 프로세스 실행하기 (0) | 2021.05.12 |
[C#/COMMON] 윈도우즈 서비스에서 시스템 권한으로 프로세스 실행하기 (0) | 2021.05.12 |
[C#/COMMON] Process 클래스 : Kill 메소드를 사용해 특정 디렉토리 내 프로세스 죽이기 (0) | 2021.05.11 |
댓글을 달아 주세요