Thực hiện của bạn là chính xác. Thật không may, .NET Framework không cung cấp loại băm đồng thời tích hợp sẵn. Tuy nhiên, có một số cách giải quyết.
Đồng thời Từ điển (khuyên dùng)
Điều đầu tiên này là sử dụng lớp ConcurrentDictionary<TKey, TValue>
trong không gian tên System.Collections.Concurrent
. Trong trường hợp, giá trị là vô nghĩa, vì vậy chúng ta có thể sử dụng một đơn giản byte
(1 byte trong bộ nhớ).
private ConcurrentDictionary<string, byte> _data;
Đây là tùy chọn được đề xuất vì loại này là an toàn cho luồng và cung cấp cho bạn những lợi thế giống như HashSet<T>
ngoại trừ khóa và giá trị là các đối tượng khác nhau.
Nguồn: MSDN xã hội
Đồng thờiBag
Nếu bạn không bận tâm về các mục trùng lặp, bạn có thể sử dụng lớp ConcurrentBag<T>
trong cùng một không gian tên của lớp trước đó.
private ConcurrentBag<string> _data;
Tự thực hiện
Cuối cùng, như bạn đã làm, bạn có thể thực hiện kiểu dữ liệu của riêng mình, sử dụng khóa hoặc các cách khác mà .NET cung cấp cho bạn để đảm bảo an toàn cho chuỗi. Dưới đây là một ví dụ tuyệt vời: Cách triển khai ConcurrencyHashset trong .Net
Hạn chế duy nhất của giải pháp này là loại HashSet<T>
không truy cập chính thức đồng thời, ngay cả đối với các hoạt động đọc.
Tôi trích dẫn mã của bài đăng được liên kết (ban đầu được viết bởi 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
}
}
EDIT: Di chuyển các phương thức khóa lối vào bên trong các try
khối, vì chúng có thể ném ngoại lệ và thực hiện các hướng dẫn có trong các finally
khối.
System.Collections.Concurrent