구현이 정확합니다. 불행히도 .NET Framework는 내장 동시 해시 셋 유형을 제공하지 않습니다. 그러나 몇 가지 해결 방법이 있습니다.
동시 사전 (권장)
첫 번째 ConcurrentDictionary<TKey, TValue>
는 네임 스페이스 에서 클래스를 사용하는 것 System.Collections.Concurrent
입니다. 이 경우 값이 의미가 없으므로 단순 byte
(메모리에서 1 바이트)을 사용할 수 있습니다 .
private ConcurrentDictionary<string, byte> _data;
유형은 스레드로부터 안전 HashSet<T>
하고 키와 값이 다른 객체와 동일한 이점을 제공하기 때문에 권장되는 옵션 입니다.
출처 : 소셜 MSDN
동시 가방
중복 항목이 마음에 들지 않으면 ConcurrentBag<T>
이전 클래스와 동일한 네임 스페이스에서 클래스 를 사용할 수 있습니다 .
private ConcurrentBag<string> _data;
자기 구현
마지막으로, 잠금이나 .NET이 스레드 안전을 제공하는 다른 방법을 사용하여 자체 데이터 형식을 구현할 수 있습니다. 다음은 좋은 예입니다. .Net에서 ConcurrentHashSet을 구현하는 방법
이 솔루션의 유일한 단점은 HashSet<T>
읽기 작업의 경우에도 형식 이 공식적으로 동시 액세스하지 않는다는 것입니다.
링크 된 게시물의 코드를 인용하십시오 (원래 Ben Mosher 작성 ).
using System;
using System.Collections.Generic;
using System.Threading;
namespace BlahBlah.Utilities
{
public class ConcurrentHashSet<T> : IDisposable
{
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private readonly HashSet<T> _hashSet = new HashSet<T>();
#region Implementation of ICollection<T> ...ish
public bool Add(T item)
{
_lock.EnterWriteLock();
try
{
return _hashSet.Add(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
public void Clear()
{
_lock.EnterWriteLock();
try
{
_hashSet.Clear();
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
public bool Contains(T item)
{
_lock.EnterReadLock();
try
{
return _hashSet.Contains(item);
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
public bool Remove(T item)
{
_lock.EnterWriteLock();
try
{
return _hashSet.Remove(item);
}
finally
{
if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();
}
}
public int Count
{
get
{
_lock.EnterReadLock();
try
{
return _hashSet.Count;
}
finally
{
if (_lock.IsReadLockHeld) _lock.ExitReadLock();
}
}
}
#endregion
#region Dispose
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
if (_lock != null)
_lock.Dispose();
}
~ConcurrentHashSet()
{
Dispose(false);
}
#endregion
}
}
편집 : 입구 잠금 방법을 이동하면 try
예외가 발생하고 finally
블록에 포함 된 명령을 실행할 수 있으므로 블록을 ouside하십시오 .
System.Collections.Concurrent