#c# #multithreading #list #collections #concurrency
#c# #многопоточность #Список #Коллекции #параллелизм
Вопрос:
У меня был List<T>
, использовал AsReadOnly()
метод и сохранил результат ReadOnlyCollection<T>
. Теперь я работаю в потоках, и мне нужно сделать то же самое, но SynchronizedCollection<T>
вместо List<T>
и SynchronizedReadOnlyCollection<T>
вместо ReadOnlyCollection<T>
Как это сделать?
Ответ №1:
Поскольку SynchronizedCollection<T> : IEnumerable<T>
вы могли бы инициализировать новый экземпляр на SynchronizedReadOnlyCollection<T>
основе вашего существующего SynchronizedCollection<T>
, используя конструктор
var readOnlyCollection = new SynchronizedReadOnlyCollection(synchronizedCollection.SyncRoot,
syncronizedCollection);
Я также думаю о другом подходе. Разница в том, что при первом подходе у вас действительно есть снимок SynchronizedCollection<T>
, но при этом у вас есть только оболочка, доступная только для чтения (если вы добавите что-то в исходную коллекцию, это также обновит коллекцию, доступную только для чтения)
public static class SynchronizedCollectionExtension
{
public static IReadOnlyCollection<T> AsReadOnly<T>(this SynchronizedCollection<T> value)
{
lock (value.SyncRoot)
{
// this call is not expensive as it is just a thin wrapper around the IList<T>
return new ReadOnlyCollection<T>(value);
}
}
}
IReadOnlyCollection<int> readOnlyCollection = collection.AsReadOnly();
Комментарии:
1. Спасибо за ответ! Могу ли я сделать это без создания нового объекта? Если у меня есть свойство для доступа к коллекции только для чтения, это довольно дорого.
Ответ №2:
Если у вас есть данные в перечислимом типе, просто передайте их в синхронизированные конструкторы классов:
List<T> data = new List<T>();
var syncRoot = new object();
var syncCollection = new SynchronizedCollection<T>(syncRoot, data);
var synchronizedReadOnlyCollection = new SynchronizedReadOnlyCollection<T>(syncRoot, data);
Комментарии:
1. Спасибо за ответ! Могу ли я сделать это без создания нового объекта? Если у меня есть свойство для доступа к коллекции только для чтения, это довольно дорого.
2. Просто сохраните коллекцию синхронизации как переменную-член.
3. Я имею в виду это
new SynchronizedReadOnlyCollection<T>(syncRoot, data);