Ошибка в TypeAccessor.GetCustomTypeDescriptor(Type type)
От: Rollback Россия  
Дата: 03.08.09 07:01
Оценка: 4 (1)
Фрагмент кода из класса BLToolkit.Reflection.TypeAccessor

private static readonly Hashtable _descriptors = new Hashtable();

public static ICustomTypeDescriptor GetCustomTypeDescriptor(Type type)
{
    ICustomTypeDescriptor descriptor = (ICustomTypeDescriptor)_descriptors[type];

    if (descriptor == null)
    {
        descriptor = new CustomTypeDescriptorImpl(type);
        // ????????????????????????????????????????????????????????
        // ?? тут не хватает _descriptors.Add(type, descriptor); ??
        // ????????????????????????????????????????????????????????
    }

    return descriptor;
}

ЗЫ: Возможно баян, или я чего-то не понял, сильно не ругайте, если зря побеспокоил.
Re: Ошибка в TypeAccessor.GetCustomTypeDescriptor(Type type)
От: ili Россия  
Дата: 05.08.09 06:42
Оценка:
Здравствуйте, Rollback, Вы писали:

R>ЗЫ: Возможно баян, или я чего-то не понял, сильно не ругайте, если зря побеспокоил.


fixed due to 769 revision
Re[2]: Ошибка в TypeAccessor.GetCustomTypeDescriptor(Type ty
От: Rollback Россия  
Дата: 06.08.09 03:17
Оценка:
ili>fixed due to 769 revision

Спасибо!
Re[2]: Ошибка в TypeAccessor.GetCustomTypeDescriptor(Type ty
От: WolfHound  
Дата: 18.09.09 15:22
Оценка:
Здравствуйте, ili, Вы писали:

R>>ЗЫ: Возможно баян, или я чего-то не понял, сильно не ругайте, если зря побеспокоил.

ili>fixed due to 769 revision
Не-не-не! Девид Блейн! Не-не-не!
Это не фиксед.
Это race condition.
Смотри строки с !!!
                private static readonly Hashtable _descriptors = new Hashtable();

                public static ICustomTypeDescriptor GetCustomTypeDescriptor(Type type)
                {
                        ICustomTypeDescriptor descriptor = (ICustomTypeDescriptor)_descriptors[type];//!!!

                        if (descriptor == null)
                        {
                                lock (_descriptors.SyncRoot)
                                {
                                        descriptor = (ICustomTypeDescriptor)_descriptors[type];
                                        
                                        if (descriptor == null)
                                        {
                                                descriptor = new CustomTypeDescriptorImpl(type);
                                                
                                                _descriptors.Add(type, descriptor);//!!!
                                        }
                                }
                        }
                        return descriptor;
                }

Кстати, а почему Hashtable? Всроде первый фреймворк забросили?
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Ошибка в TypeAccessor.GetCustomTypeDescriptor(Type ty
От: ili Россия  
Дата: 21.09.09 07:49
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Не-не-не! Девид Блейн! Не-не-не!

WH>Это не фиксед.
WH>Это race condition.
WH>Смотри строки с !!!
WH>
WH>                private static readonly Hashtable _descriptors = new Hashtable();

WH>                public static ICustomTypeDescriptor GetCustomTypeDescriptor(Type type)
WH>                {
WH>                        ICustomTypeDescriptor descriptor = (ICustomTypeDescriptor)_descriptors[type];//!!!

WH>                        if (descriptor == null)
WH>                        {
WH>                                lock (_descriptors.SyncRoot)
WH>                                {
WH>                                        descriptor = (ICustomTypeDescriptor)_descriptors[type]; // вот эта строчка
                                        
WH>                                        if (descriptor == null)
WH>                                        {
WH>                                                descriptor = new CustomTypeDescriptorImpl(type);
                                                
WH>                                                _descriptors.Add(type, descriptor);//!!!
WH>                                        }
WH>                                }
WH>                        }
WH>                        return descriptor;
WH>                }
WH>


ну посмотрел, и ничо не понял... в чем трабла-то? я того, необразованный, чо такое "race condition" не знаю
вроде догадываюсь... к чему-ты, но там сеть еще одна строчка, не?

WH>Кстати, а почему Hashtable? Всроде первый фреймворк забросили?


а там исторически много где Hashtable пользуется. А переделывать на Dictionary<K, V>... я как-то думал в порядке безделья... вот только бенефита особого нет. словарь даст такой прирост производительности, что в микроскоп не разглядишь...
Re[4]: race condition
От: Блудов Павел Россия  
Дата: 24.09.09 02:51
Оценка:
Здравствуйте, ili, Вы писали:

ili>ну посмотрел, и ничо не понял... в чем трабла-то? я того, необразованный, чо такое "race condition" не знаю

ili>вроде догадываюсь... к чему-ты, но там сеть еще одна строчка, не?

Андрей прав, одновременный вызов TypeAccessor.GetCustomTypeDescriptor из 32 разных ниток приведёт к тому, что часть дескрипторов будет утеряна. Тут нужно либо заменить Hashtable на Dictionary<,> у которого таких проблем нет, либо защитить _descriptors.Add(type, descriptor) при помощи lock (_descriptors.SyncRoot).
Re[5]: race condition
От: ili Россия  
Дата: 24.09.09 05:09
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Андрей прав, одновременный вызов TypeAccessor.GetCustomTypeDescriptor из 32 разных ниток приведёт к тому, что часть дескрипторов будет утеряна. Тут нужно либо заменить Hashtable на Dictionary<,> у которого таких проблем нет, либо защитить _descriptors.Add(type, descriptor) при помощи lock (_descriptors.SyncRoot).


я так чего-то не понял, так:
lock (_descriptors.SyncRoot)
{
    descriptor = (ICustomTypeDescriptor)_descriptors[type];
                                        
    if (descriptor == null)
    {
        descriptor = new CustomTypeDescriptorImpl(type);
        
        lock (_descriptors.SyncRoot) // так?...
        {                                        
            _descriptors.Add(type, descriptor);//!!!
        }

    }
}


и чем это спасёт? там уже есть один lock от второго врят ли легче станет.
и почему Dictionary<,> не имеет таких проблем? почему 32 потока? дайте хоть ссылку на почитать, а то гугль мне что-то невнятное говорит, а кики рекомендует спасаться синхронизацией.
Re[6]: race condition
От: Блудов Павел Россия  
Дата: 24.09.09 05:58
Оценка:
Здравствуйте, ili, Вы писали:

ili>и чем это спасёт? там уже есть один lock от второго врят ли легче станет.

И правда есть. Тогда конечно вторая блокировка вообще безсмысленна.
ili>и почему Dictionary<,> не имеет таких проблем?
Ни почему. Тоже перепутал.
Собственно вот код:
public bool TryGetValue(TKey key, out TValue value)
{
    int index = FindEntry(key);
    if (index >= 0)
    {
        value = entries[index].value;
        return true;
    }
    value = default(TValue);
    return false;
}

Тут сначала ищется индекс в массиве entries, а затем возвращается значение по этому индексу.
А вот код метода Resize
private void Resize()
{
// ...
    Entry<TKey, TValue>[] destinationArray = new Entry<TKey, TValue>[prime];
    Array.Copy(entries, 0, destinationArray, 0, count);
//...
    entries = destinationArray;
}

Тут сначала делается точная копия массива entities, но большего размера, а потом заменяется ссылка на сам массив.
Даже если предположить, что в момент выполнения
value = entries[index].value;

произойдёт подмена этих entities, то будет возвращён либо элемент из старого массива, либо из нового, который включает в себя старый массив целиком. Даже сборщик мусора не сможет нам помешать, т.е. локальная ссылка на старый entities всё ещё лежит в стеке.
Так что текущая реализация Dictionary<,> позволяет доверять возвращаемому TryGetValue значению.
А вот параллельные вызовы метода Dictionary<,>.Add() без синхронизации могут сломать цивилизацию.
Так что Dictionary<,> ничем не лучше (но и не хуже) Hashtable.

ili>почему 32 потока?

Число круглое.
ili>дайте хоть ссылку на почитать, а то гугль мне что-то невнятное говорит, а кики рекомендует спасаться синхронизацией.
Если гугль говорит про
http://blogs.msdn.com/kimhamil/archive/2008/03/08/hashtable-and-dictionary-thread-safety-considerations.aspx
то это ересь. См. выше.

В общем не обращай внимания. А я пойду высплюсь как следует.
Re[7]: race condition
От: ili Россия  
Дата: 24.09.09 06:56
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

ili>>почему 32 потока?

БП>Число круглое.

БП>В общем не обращай внимания. А я пойду высплюсь как следует.


ага, тебе по ходу надо
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.