Потокобезопасный IEnumerable
От: Аноним  
Дата: 09.08.10 04:14
Оценка:
Добрый день,
понадобилось на днях реализовать потокобезопанную коллекцию реализующую интерфейс IList. Задача вроде тривиальная.
Но наткнулся на следюующую проблему. Как реализовать безопасный IEnumerable? Делать блокировку на всё время перебора коллекции, как мне кажется неправильно, делать клон колееции при вызове GetEnumerator еще хуже. Подскажите путь.
Re: Потокобезопасный IEnumerable
От: Nuseraro Россия  
Дата: 09.08.10 04:55
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добрый день,

А>понадобилось на днях реализовать потокобезопанную коллекцию реализующую интерфейс IList. Задача вроде тривиальная.
А>Но наткнулся на следюующую проблему. Как реализовать безопасный IEnumerable? Делать блокировку на всё время перебора коллекции, как мне кажется неправильно, делать клон колееции при вызове GetEnumerator еще хуже. Подскажите путь.

Это вроде легко гуглится. Например, http://www.codeproject.com/KB/cs/safe_enumerable.aspx.
Homo Guglens
Re: Потокобезопасный IEnumerable
От: samius Япония http://sams-tricks.blogspot.com
Дата: 09.08.10 05:34
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Делать блокировку на всё время перебора коллекции, как мне кажется неправильно, делать клон колееции при вызове GetEnumerator еще хуже. Подскажите путь.


Подскажите желаемое поведение перечислителя при изменениях коллекции. Если блокировать и копировать по-вашему неправильно, то следует ли из этого, что перечислитель должен отражать изменения, сделанные после создания перечислителя?
Re[2]: Потокобезопасный IEnumerable
От: Аноним  
Дата: 09.08.10 07:42
Оценка:
Да именно так.
Энумератор должен вести как указатель на элемент свзанного списка.
Т.е. если в коллекию добавился новый элемен и он находится после текущего, то энумератор должен пройти через него.
Если допустим элемент на который в данный момент eазывает энкмератор будет удален, то функция MoveNext вернет false

Здравствуйте, samius, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>Делать блокировку на всё время перебора коллекции, как мне кажется неправильно, делать клон колееции при вызове GetEnumerator еще хуже. Подскажите путь.


S>Подскажите желаемое поведение перечислителя при изменениях коллекции. Если блокировать и копировать по-вашему неправильно, то следует ли из этого, что перечислитель должен отражать изменения, сделанные после создания перечислителя?
Re[3]: Потокобезопасный IEnumerable
От: samius Япония http://sams-tricks.blogspot.com
Дата: 09.08.10 07:58
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Да именно так.

А>Энумератор должен вести как указатель на элемент свзанного списка.
А>Т.е. если в коллекию добавился новый элемен и он находится после текущего, то энумератор должен пройти через него.
А>Если допустим элемент на который в данный момент eазывает энкмератор будет удален, то функция MoveNext вернет false

технически это выполнимо. Но вот интересно, что должен вернуть перечислитель при обращении к свойству Current, если после успешного MoveNext на последний элемент, последний элемент был удален другим потоком?
Re[4]: Потокобезопасный IEnumerable
От: Аноним  
Дата: 09.08.10 08:39
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>Да именно так.

А>>Энумератор должен вести как указатель на элемент свзанного списка.
А>>Т.е. если в коллекию добавился новый элемен и он находится после текущего, то энумератор должен пройти через него.
А>>Если допустим элемент на который в данный момент eазывает энкмератор будет удален, то функция MoveNext вернет false

S>технически это выполнимо. Но вот интересно, что должен вернуть перечислитель при обращении к свойству Current, если после успешного MoveNext на последний элемент, последний элемент был удален другим потоком?


Если мы упешно выполнини MoveNext то Current должен возврашать этот элемент. Если после этого мы вызовем Reset() то перечислитель должен будет указывать на начало списка состоящего из 1 элемента.
Re[5]: Потокобезопасный IEnumerable
От: samius Япония http://sams-tricks.blogspot.com
Дата: 09.08.10 09:07
Оценка:
Здравствуйте, Аноним, Вы писали:

S>>технически это выполнимо. Но вот интересно, что должен вернуть перечислитель при обращении к свойству Current, если после успешного MoveNext на последний элемент, последний элемент был удален другим потоком?


А>Если мы упешно выполнини MoveNext то Current должен возврашать этот элемент. Если после этого мы вызовем Reset() то перечислитель должен будет указывать на начало списка состоящего из 1 элемента.


т.е. перечислитель в момент MoveNext кэширует текущий элемент и в качестве Current возвращает именно его, а не текущий? Т.е. если после MoveNext текущий элемент списка изменится, то перечислитель должен вернуть кэшированный или новый?
Re[6]: Потокобезопасный IEnumerable
От: Аноним  
Дата: 09.08.10 11:29
Оценка:
Здравствуйте, samius, Вы писали:
S>т.е. перечислитель в момент MoveNext кэширует текущий элемент и в качестве Current возвращает именно его, а не текущий? Т.е. если после MoveNext текущий элемент списка изменится, то перечислитель должен вернуть кэшированный или новый?
В моемент MoveNext перечислитель должен переместить указатель на следующий элемент и "помнить" этот указатель до следующего вызова MoveNext. Т.е. если сам объект изменился то при получении Current должен быть получен изменнеый объект.

Вот как я это вижу:

начальное сосояние

А -> В -> С — список
^- перечислитель указывает на начало списка

Вызываем MoveNext
А -> В -> С
^- перечислитель указывает на элемент B

Удалям элемент B ис списка
получаем список
А -> С
отдельно элемент B на который указывает перечилитель
^- перечислитель указывает на элемент B
Re[7]: Потокобезопасный IEnumerable
От: samius Япония http://sams-tricks.blogspot.com
Дата: 09.08.10 11:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, samius, Вы писали:

S>>т.е. перечислитель в момент MoveNext кэширует текущий элемент и в качестве Current возвращает именно его, а не текущий? Т.е. если после MoveNext текущий элемент списка изменится, то перечислитель должен вернуть кэшированный или новый?
А>В моемент MoveNext перечислитель должен переместить указатель на следующий элемент и "помнить" этот указатель до следующего вызова MoveNext. Т.е. если сам объект изменился то при получении Current должен быть получен изменнеый объект.

А>Вызываем MoveNext

А> А -> В -> С
А>      ^- перечислитель указывает на элемент B

А>Удалям элемент B ис списка
А>получаем список
А> А -> С
А> отдельно элемент B на который указывает перечилитель
А>                  ^- перечислитель указывает на элемент B

Не нравится мне то, что в одном случае перечислитель вернет обновленный элемент, а в другом — закэшированный во время MoveNext() — очень неочевидная логика.

А что будет, если после MoveNext на B, будет удален элемент A? Current вернет B или C?
Re: Потокобезопасный IEnumerable
От: dsorokin Россия  
Дата: 09.08.10 11:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добрый день,

А>понадобилось на днях реализовать потокобезопанную коллекцию реализующую интерфейс IList. Задача вроде тривиальная.

Используй иммутабельные структуры данных. И задача не так тривиальна. Над ней бились и продолжают биться лучшие программистские умы вроде Окасаки
Re[8]: Потокобезопасный IEnumerable
От: Аноним  
Дата: 09.08.10 11:56
Оценка:
А>> А -> В -> С
А>> ^- перечислитель указывает на элемент B

А>>Удалям элемент B ис списка

А>>получаем список
А>> А -> С
А>> отдельно элемент B на который указывает перечилитель
А>> ^- перечислитель указывает на элемент B
S>[/code]
S>Не нравится мне то, что в одном случае перечислитель вернет обновленный элемент, а в другом — закэшированный во время MoveNext() — очень неочевидная логика.
Элементы не кэшируются. При вызове Current для ссылочных типов должен возврящаться именно то объект который был в коллекции

S>А что будет, если после MoveNext на B, будет удален элемент A? Current вернет B или C?


Current должен вернуть B
При следующем вызове MoveNext Current должен возвращать C.
Если Вызвать Reset то Перечислитель должен перейти на B
Re[9]: Потокобезопасный IEnumerable
От: samius Япония http://sams-tricks.blogspot.com
Дата: 09.08.10 13:12
Оценка:
Здравствуйте, Аноним, Вы писали:

S>>Не нравится мне то, что в одном случае перечислитель вернет обновленный элемент, а в другом — закэшированный во время MoveNext() — очень неочевидная логика.

А>Элементы не кэшируются. При вызове Current для ссылочных типов должен возврящаться именно то объект который был в коллекции

Как вернуть элемент, который был, если его нет и элементы не кэшируются?

S>>А что будет, если после MoveNext на B, будет удален элемент A? Current вернет B или C?


А>Current должен вернуть B

А>При следующем вызове MoveNext Current должен возвращать C.
А>Если Вызвать Reset то Перечислитель должен перейти на B

Все стесняюсь спросить, как реализован список? Связный, или на основе массива?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.