[解決済み] .NET FrameworkでHashSet<T>を並列化する?
質問
以下のようなクラスがあります。
class Test{
public HashSet<string> Data = new HashSet<string>();
}
私は異なるスレッドからフィールド "Data" を変更する必要があるので、私は現在のスレッドセーフな実装についていくつかの意見が欲しいです。
class Test{
public HashSet<string> Data = new HashSet<string>();
public void Add(string Val){
lock(Data) Data.Add(Val);
}
public void Remove(string Val){
lock(Data) Data.Remove(Val);
}
}
フィールドに直接アクセスして、複数のスレッドによる同時アクセスから保護する、より良い解決策はないでしょうか?
どのように解決するのですか?
あなたの実装は正しいです。.NET Frameworkは、残念ながら、組み込みの同時実行ハッシュセット型を提供しません。しかし、いくつかの回避策があります。
ConcurrentDictionary (推奨)
この最初のものは、クラス
ConcurrentDictionary<TKey, TValue>
を名前空間
System.Collections.Concurrent
. の場合、その値は無意味なので、単純な
byte
(メモリに1バイト)。
private ConcurrentDictionary<string, byte> _data;
この型はスレッドセーフで,かつ
HashSet<T>
ただし、keyとvalueは異なるオブジェクトである。
出典 ソーシャルMSDN
コンカレントバッグ
エントリーの重複を気にしないのであれば、クラス
ConcurrentBag<T>
を、前のクラスと同じ名前空間で使用します。
private ConcurrentBag<string> _data;
自己完結型
最後に、あなたがしたように、ロックや.NETが提供するスレッドセーフになるための他の方法を使用して、独自のデータ型を実装することができます。ここに素晴らしい例があります。 .NetでConcurrentHashSetを実装する方法
このソリューションの唯一の欠点は、タイプ
HashSet<T>
は、読み込み操作であっても、公式には同時アクセスできない。
リンク先の投稿のコードを引用します(原文ママ ベン・モシャー ).
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です。
エントランス・ロック・メソッドを
try
ブロックに含まれる命令が例外をスローして実行される可能性があるからです。
finally
ブロックを作成します。
関連
-
[解決済み】統合マネージドパイプラインモードで適用されないASP.NETの設定が検出された
-
[解決済み】「namespace x already contains a definition for x」エラーの修正方法は?VS2010にコンバートした後に発生しました。
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み】HRESULTからの例外:0x800A03ECエラー
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み] [Solved] .NETでスレッドの終了を待つには?
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み】Queue.Queueとcollections.dequeの比較
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み】WSACancelBlockingCallの例外について
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み] [Solved] .NETでスレッドの終了を待つには?
-
[解決済み】IntPtrとは一体何なのか?
-
[解決済み】WebResource.axdとは何ですか?