У меня есть общий объект между потоками, который используется для хранения информации о состоянии файла.Объект, содержащий информацию, - это следующий класс:
/// <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 ["ключ"];
Словарь может быть изменен во время выполнения.Я не вижу здесь никаких проблем.Или я не прав?Проблема, на мой взгляд, заключается в перечислителе, потому что я хочу создать перечислитель, который перебирает всю коллекцию.Как мне это сделать?Я думал об этих трех решениях:
- Создание перечислителя следующим образом: http://www.codeproject.com/Articles/56575/Thread-safe-enumeration-in-C (но с использованием ReaderWriterLockSlim)
- Предоставление объекта блокировки, как это делает SyncRoot (нос ReaderWriterLockSlim), поэтому вызывающая сторона вызывает методы чтения входа и выхода.
- Вместо этого используйте базу данных (SQLite fx), хранящую информацию.
Проблема с номером 1 состоит в том, что:
- он использует конструктор для входа в режим чтения.Что если GetEnumerator () вызывается вручную, не используя foreach?И не забудьте вызвать dispose.
- Я не знаю, хороший ли это стиль кодирования.Несмотря на то, что мне нравится код.
- Если вызывающая сторона использует foreach, я не знаю, что может сделать вызывающая сторона между созданием экземпляра перечислителя и вызовом dispose.Если я понял документацию, которую я прочитал правильно, это может привести к блокировке писателя до тех пор, пока остается один читатель, выполняющий тяжелую работу.
Проблема с номером 2):
- Мне не нравится выставлять это.Я знаю, что .NET API это делает, но мне это не нравится.
- Вызывающий абонент должен правильно входить и выходить
Нет проблем с 3) Iмои глаза.Но я делаю этот небольшой проект как проект свободного времени, и я хочу узнать больше о многопоточности и рефлексии, поэтому я хочу оставить это в качестве последнего варианта.Причина, по которой я хочу перебирать коллекцию во время выполнения, состоит в том, что я хочу найти значения, которые соответствуют некоторым критериям.
Может быть, только я изобрел проблему?
Я знаю 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.