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