개발/C#
[C#] ConcurrentList
min1119
2023. 12. 6. 02:40
- thread-safe하게 read, write가 가능하고 인덱서 사용이 가능한 List가 필요하여 생성한 자료구조 클래스
- ReaderWriterLockSlim을 사용하여 필요 자원 잠금
- try문의 finally를 이용하여 작업 진행 후 Lock 해제
- 코드 재사용성을 위해 일괄적으로 내부에서 lock 사용 및 대리자를 호출하는 함수 사용
public class ConcurrentList<T>
{
~ConcurrentList()
{
_lockSlim?.Dispose();
}
public T? this[int index]
{
get
{
if (index < 0 || _values.Count <= index)
{
return default;
}
return (T?)ReadExecute(() => _values[index]);
}
set
{
if (index < 0 || _values.Count <= index)
{
return;
}
WriteExecute(() => _values[index] = value);
}
}
public int Count => (int)ReadExecute(() => _values.Count)!;
public bool Contains(T obj) => (bool)ReadExecute(() => _values.Contains(obj))!;
public void Add(T obj, int timeout = 0) => WriteExecute(() => _values.Add(obj), timeout);
public void Remove(T obj, int timeout = 0) => WriteExecute(() => _values.Remove(obj), timeout);
public void Clear(int timeout = 0) => WriteExecute(() => _values.Clear(), timeout);
private void WriteExecute(Delegate @delegate, int timeout = 0, params object?[]? args)
{
if (timeout <= 0)
{
_lockSlim.EnterWriteLock();
}
else
{
_lockSlim.TryEnterWriteLock(timeout);
}
try
{
@delegate.DynamicInvoke(args);
}
finally
{
_lockSlim.ExitWriteLock();
}
}
private object? ReadExecute(Delegate @delegate, int timeout = 0, params object?[]? args)
{
if (timeout <= 0)
{
_lockSlim.EnterReadLock();
}
else
{
_lockSlim.TryEnterReadLock(timeout);
}
try
{
return @delegate.DynamicInvoke(args);
}
finally
{
_lockSlim.ExitReadLock();
}
}
private ReaderWriterLockSlim _lockSlim = new();
private List<T?> _values = new();
}
Git : https://github.com/ChoiMingyeong/Devoram.git
GitHub - ChoiMingyeong/Devoram: Devoram Engine Repository
Devoram Engine Repository. Contribute to ChoiMingyeong/Devoram development by creating an account on GitHub.
github.com