Ответвления темы являются обычно легкими ответвлениями, которые Вы создаете локально и которые имеют имя, которое является понятным для Вы . Они - то, где Вы могли бы сделать работу для исправления ошибки или функции (их также называют ответвлениями функции), который, как ожидают, займет время для завершения.
Другой тип ответвления является "удаленным ответвлением" или "удаленно отслеживающим ответвлением". Этот тип ответвления следует за разработкой кого-то else's работа и хранится в Вашем собственном репозитории. Вы периодически обновляете это ответвление (использующий git fetch
) для отслеживания то, что происходит в другом месте. Когда Вы готовы догнать всех изменения else, Вы использовали бы git pull
, чтобы и выбрать и объединиться.
я также видел другой вид ответвления, которое является по существу абсолютно отдельным деревом файлов в том же репозитории. Например, сам репозиторий Мерзавца содержит головы, названные человек и html, которые содержат совершенно другое содержание от ведущее устройство ответвление. Я не знаю то, чем обычно называют эти типы ответвлений.
Поскольку исключение происходит внутри кода Словаря
, это означает, что вы обращаются к одному и тому же экземпляру Dictionary
из более чем одного потока одновременно.
Вам необходимо синхронизировать код в методе GetInstance
, чтобы только один поток одновременно обращался словарь
.
Редактировать:
Блокируйте доступы по отдельности, чтобы вы не оказались внутри блокировки при выполнении (предположительно) трудоемкой загрузки:
private static object _sync = new object();
public static object GetInstance(string key) {
object instance = null;
bool found;
lock (_sync) {
found = Instances.TryGetValue(key, out instance);
}
if (!found) {
instance = LoadInstance(key);
lock (_sync) {
object current;
if (Instances.TryGetValue(key, out current)) {
// some other thread already loaded the object, so we use that instead
instance = current;
} else {
Instances[key] = instance;
}
}
}
return instance;
}
Цитата http://msdn.microsoft.com/en-us/library/xfhwa508.aspx (курсив добавлен мной):
" Thread Safety
Общедоступные статические (общие в Visual Basic) члены этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют безопасность потоков.
A Dictionary <(Of <(TKey, TValue> )>)
может поддерживать несколько считывателей одновременно, пока коллекция не изменена. Даже в этом случае перечисление через коллекцию по своей сути не является потокобезопасной процедурой. В редких случаях, когда перечисление соперничает с доступом на запись, коллекция должна быть заблокирована на протяжении всего перечисления. Чтобы разрешить доступ к коллекции нескольким потокам для чтения и записи, вы должны реализовать свою собственную синхронизацию ».
Думаю, ваш Экземпляр
Словарь
не является нулевым. Ваше исключение находится внутри метода Insert
- это означает, что во время выполнения существует объект Dictionary
(Кроме того, как вы сказали, у вас уже есть TryGetValue
раньше, по той же ссылке)
Может быть, ваш ключ
имеет значение NULL?
Только что проверил - TryGetValue
выдает исключение ArgumentNullException, когда получает нулевой ключ, и вставляет с нулевым ключом . Но какой класс вы используете в своем примере? Я использовал общий IDictionary
, но я вижу, что вы используете не общий. Это класс, унаследованный вами от DictionaryBase
или, может быть, HashTable
?
Лучшим решением было бы создать синхронизированный словарь. Вот тот, который сработает в этой ситуации. Я считаю, что ReaderWriterLockSlim - лучший объект синхронизации для использования в этой ситуации. Запись в словарь будет довольно редкой. Большую часть времени ключ будет в словаре. Я не реализовал все методы словаря, только те, которые использовались в данном случае, так что это не полный синхронизированный словарь.
public sealed class SynchronizedDictionary<TKey, TValue>
{
private readonly Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
private readonly ReaderWriterLockSlim readerWriterLock = new ReaderWriterLockSlim();
public TValue this[TKey key]
{
get
{
readerWriterLock.EnterReadLock();
try
{
return this.dictionary[key];
}
finally
{
readerWriterLock.ExitReadLock();
}
}
set
{
readerWriterLock.EnterWriteLock();
try
{
this.dictionary[key] = value;
}
finally
{
readerWriterLock.ExitWriteLock();
}
}
}
public bool TryGetValue(TKey key, out TValue value)
{
readerWriterLock.EnterReadLock();
try
{
return this.dictionary.TryGetValue(key, out value);
}
finally
{
readerWriterLock.ExitReadLock();
}
}
}