ファイルの状態情報を保持するために使用されるスレッド間で共有オブジェクトがあります。情報を保持するオブジェクトは次のクラスです。
/// <summary>
/// A synchronized dictionary class.
/// Uses ReaderWriterLockSlim to handle locking. The dictionary does not allow recursion by enumeration. It is purly used for quick read access.
/// </summary>
/// <typeparam name="T">Type that is going to be kept.</typeparam>
public sealed class SynchronizedDictionary<U,T> : IEnumerable<T>
{
private System.Threading.ReaderWriterLockSlim _lock = new System.Threading.ReaderWriterLockSlim();
private Dictionary<U, T> _collection = null;
public SynchronizedDictionary()
{
_collection = new Dictionary<U, T>();
}
/// <summary>
/// if getting:
/// Enters read lock.
/// Tries to get the value.
///
/// if setting:
/// Enters write lock.
/// Tries to set value.
/// </summary>
/// <param name="key">The key to fetch the value with.</param>
/// <returns>Object of T</returns>
public T this[U key]
{
get
{
_lock.EnterReadLock();
try
{
return _collection[key];
}
finally
{
_lock.ExitReadLock();
}
}
set
{
Add(key, value);
}
}
/// <summary>
/// Enters write lock.
/// Removes key from collection
/// </summary>
/// <param name="key">Key to remove.</param>
public void Remove(U key)
{
_lock.EnterWriteLock();
try
{
_collection.Remove(key);
}
finally
{
_lock.ExitWriteLock();
}
}
/// <summary>
/// Enters write lock.
/// Adds value to the collection if key does not exists.
/// </summary>
/// <param name="key">Key to add.</param>
/// <param name="value">Value to add.</param>
private void Add(U key, T value)
{
_lock.EnterWriteLock();
if (!_collection.ContainsKey(key))
{
try
{
_collection[key] = value;
}
finally
{
_lock.ExitWriteLock();
}
}
}
/// <summary>
/// Collection does not support iteration.
/// </summary>
/// <returns>Throw NotSupportedException</returns>
public IEnumerator<T> GetEnumerator()
{
throw new NotSupportedException();
}
/// <summary>
/// Collection does not support iteration.
/// </summary>
/// <returns>Throw NotSupportedException</returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
throw new NotSupportedException();
}
}
私はこの辞書を次のように呼んでいます。SynchronizedDictionary_cache=new SynchronizedDictionary();
他のスレッドを生成して、次のようにスレッドを使用できます。_cache ["key"];
辞書は実行時に変更できます。ここでは問題ありません。それとも私は間違っていますか?私の目には、コレクションを反復処理する列挙子を作成したいので、問題は列挙子にあります。どうすればよいですか?私はこれらの3つの解決策を考えました:
- 次のような列挙子を作成します:http: //www.codeproject.com/Articles/56575/Thread-safe-enumeration-in-C (ただし、ReaderWriterLockSlimを使用)
- SyncRootと同様に(ただしReaderWriterLockSlimを使用して)ロックオブジェクトを公開し、呼び出し元がenterメソッドとexit読み取りメソッドを呼び出すようにします。
- 代わりに、情報を保持するデータベース(SQLite fx)を使用してください。
番号1)の問題は次のとおりです。
- コンストラクターを使用して読み取りモードに入ります。GetEnumerator()がforeachを使用せずに手動で呼び出された場合はどうなりますか?そして、disposeを呼び出すのを忘れてください。
- これが良いコーディングスタイルかどうかはわかりません。私はコードが好きですが。
- 呼び出し元がforeachを使用している場合、列挙子のインスタンス化と破棄の呼び出しの間に呼び出し元が何をする可能性があるのかわかりません。私が正しく読んだドキュメントを理解していれば、重い作業をしているリーダーが1人残っている限り、これはライターをブロックしてしまう可能性があります。
2)の問題は次のとおりです。
- 私はこれを公開するのが好きではありません。.NET APIがそれを行うことは知っていますが、好きではありません。
- 適切に出入りするのは発信者次第です
3)目は問題ありません。しかし、私はこの小さなプロジェクトを空き時間プロジェクトとして行っており、マルチスレッドとリフレクションについてもっと学びたいので、これを最後のオプションとして残しておきたいと思います。実行時にコレクションを反復処理する理由は、いくつかの基準に一致する値を見つけたいからです。
たぶん、問題を発明したのは私だけですか?
ConcurrentDictionaryを知っていますが、これは使いたくありません。私はこのプロジェクトを遊び場として使っています。糸脱毛と反射で遊ぶ。
編集
読み書きをしているのは何なのかと聞かれました。そして、私はこの編集でこれを伝えるつもりです。私はこのクラスを読んだり書いたりしています:
public class AssemblyInformation
{
public string FilePath { get; private set; }
public string Name { get; private set; }
public AssemblyInformation(string filePath, string name)
{
FilePath = filePath;
Name = name;
}
}
私はたくさんの読み取りを行っていますが、実行時の書き込みはほとんどありません。多分私は2000年と1回の書き込みを行います。たくさんのオブジェクトもありません、多分200。