Программируем на C# 8.0. Разработка приложений
Қосымшада ыңғайлырақҚосымшаны жүктеуге арналған QRRuStore · Samsung Galaxy Store
Huawei AppGallery · Xiaomi GetApps

автордың кітабынан сөз тіркестері  Программируем на C# 8.0. Разработка приложений

Егор Б.
Егор Б.дәйексөз келтірді2 жыл бұрын
Простейшая реализация шаблона await public class MyAwaitableType { public MinimalAwaiter GetAwaiter() { return new MinimalAwaiter(); } public class MinimalAwaiter : INotifyCompletion { public bool IsCompleted => true; public string GetResult() => "This is a result"; public void OnCompleted(Action continuation) { throw new NotImplementedException(); } } }
1 Ұнайды
Комментарий жазу
Мурин Игорь
Мурин Игорьдәйексөз келтірді15 сағат бұрын
Наличие не обязательно означает достижимость. Объект мог стать недоступным со времени последней сборки мусора. Или, возможно, с момента выделения объекта вообще не было сборки мусора. TryGetTarget заботит не то, доступен ли объект прямо сейчас, а лишь то, обнаружил ли сборщик мусора, что он подлежит освобождению. Если объект доступен, TryGetTarget предоставляет его через параметр out, и это будет строгой ссылкой. Таким образом, если метод возвращает значение true, нам не нужно беспокоиться о том, что через мгновение объект может стать недоступным, — тот факт, что мы теперь сохранили эту ссылку в переменной, которую вызывающая сторона передала через аргумент cachedItem, сохранит и сам объект. Если TryGetTarget возвращает false, мой код удаляет соответствующую запись из словаря, поскольку она представляет объект, которого больше не существует. Это важно, потому что даже если слабая ссылка не сохранит свою цель, WeakReference<T> — это отдельный объект, и сборщик не может освободить его, пока я не удалю его из этого словаря.
Комментарий жазу
Мурин Игорь
Мурин Игорьдәйексөз келтірді15 сағат бұрын
Этот кэш хранит все значения с помощью WeakReference<T>. Его метод Add передает объект, для которого мы хотели бы использовать слабую ссылку в качестве аргумента конструктора для нового объекта WeakReference<T>. Метод TryGetValue пытается получить значение, ранее сохраненное с помощью Add. Сначала проверяется, содержит ли словарь соответствующую запись. Если содержит, то значением этой записи будет WeakReference<T>, которую мы создали ранее. Мой код вызывает метод TryGetTarget слабой ссылки, который вернет true, если объект все еще доступен, и false, если нет.
Комментарий жазу
Мурин Игорь
Мурин Игорьдәйексөз келтірді15 сағат бұрын
Листинг 7.3. Использование слабых ссылок в кэше public class WeakCache<TKey, TValue> where TValue : class { private readonly Dictionary<TKey, WeakReference<TValue>> _cache = new Dictionary<TKey, WeakReference<TValue>>(); public void Add(TKey key, TValue value) { _cache.Add(key, new WeakReference<TValue>(value)); } public bool TryGetValue(TKey key, out TValue cachedItem) { WeakReference<TValue> entry; if (_cache.TryGetValue(key, out entry)) { bool isAlive = entry.TryGetTarget(out cachedItem); if (!isAlive) { _cache.Remove(key); } return isAlive; } else { cachedItem = null; return false; } } }
Комментарий жазу
Мурин Игорь
Мурин Игорьдәйексөз келтірді15 сағат бұрын
Хотя сборщик мусора будет проходить по обычным ссылкам в полях достижимого объекта, можно сохранить слабую ссылку. Сборщик не проходит по слабым ссылкам, поэтому, если единственный способ достичь объекта — это слабые ссылки, сборщик ведет себя так, как будто объект недоступен, и удаляет его. Слабая ссылка — это способ сообщить CLR: «Не ориентируйся на меня при сохранении этого объекта, но пока он еще кому-то нужен, я бы хотел иметь к нему доступ»
Комментарий жазу
Мурин Игорь
Мурин Игорьдәйексөз келтірді15 сағат бұрын
В более общем смысле, если ваша программа делает объект достижимым, сборщик мусора не может определить, собираетесь ли вы снова использовать этот объект, поэтому он должен быть сохранен.
Комментарий жазу
Мурин Игорь
Мурин Игорьдәйексөз келтірді15 сағат бұрын
Таким образом, если вы добавляете объекты в коллекции и сохраняете доступность этих коллекций, сборщик мусора будет считать все в этих коллекциях достижимым. Удаление элементов — это ваша задача.
Комментарий жазу
Мурин Игорь
Мурин Игорьдәйексөз келтірді15 сағат бұрын
Листинг 7.2. Крайне неэффективный кусок кода static void Main(string[] args) { var numbers = new List<string>(); long total = 0; for (int i = 1; i < 100_000; ++i) { numbers.Add(i.ToString()); total += i; } Console.WriteLine("Total: {0}, average: {1}", total, total / numbers.Count); }
Комментарий жазу
Мурин Игорь
Мурин Игорьдәйексөз келтірді16 сағат бұрын
Одним из важных результатов определения достижимости является то, что сборщик мусора не смущают циклические ссылки. Это одна из причин, по которой .NET использует сборку мусора вместо подсчета ссылок (еще один популярный подход для автоматизации управления памятью). Если у вас есть два объекта, которые ссылаются друг на друга, схема подсчета ссылок решит, что оба объекта используются, поскольку каждый из них упоминается как минимум один раз. Но объекты могут быть недоступны — если нет других ссылок на них, приложение не может их использовать. Подсчет ссылок не способен этого обнаружить, поэтому он может стать причиной утечек памяти. Но для схемы, использующей сборщик мусора CLR, тот факт, что они ссылаются друг на друга, не имеет значения — сборщик мусора никогда не доберется ни до одного из них, поэтому он правильно определит, что они больше не используются.
Комментарий жазу
Мурин Игорь
Мурин Игорьдәйексөз келтірді16 сағат бұрын
Составив полный список текущих корневых ссылок для всех потоков, сборщик мусора определяет, какие объекты могут быть доступны по этим ссылкам. Он просматривает каждую ссылку по очереди, и, если она не равна null, сборщик знает, что объект, на который она ссылается, достижим. Среди них могут содержаться дубликаты, так как несколько корневых ссылок могут ссылаться на один и тот же объект. В связи с этим сборщик мусора отслеживает, какие объекты он уже встречал. Для каждого нового обнаруженного объекта сборщик добавляет все поля экземпляра ссылочного типа из этого объекта в список ссылок для оценки, опять же, избавляясь от дубликатов. (Это включает в себя скрытые поля, сгенерированные компилятором, такие как поля для автоматических свойств, которые я описал в главе 3.) Это означает, что если объект достижим, это относится и ко всем объектам, на которые он ссылается. Сборщик мусора повторяет этот процесс, пока у него не закончатся ссылки для проверки. Любые объекты, которые он не обозначил доступными, считаются недоступными, потому что сборщик просто делает то, что делает программа: использует только те объекты, которые доступны прямо или косвенно через ее переменные, временное локальное хранилище, статические поля и другие корневые ссылки.
Комментарий жазу