ta muallif kitobidan iqtiboslar  Программируем на C# 8.0. Разработка приложений

Простейшая реализация шаблона 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 kishiga yoqdi
Fikr bildirish
Существует три способа, которыми код C# обычно закрепляет блоки кучи. Вы можете сделать это явно, используя ключевое слово fixed. Это позволяет получить необработанный указатель на место хранения, такое как поле или элемент массива, и компилятор сгенерирует код, который гарантирует, что, пока фиксированный указатель находится в области доступности, блок кучи, на который он ссылается, будет закрепленным. Более распространенным способом закрепления блока является межпрограммное взаимодействие (т. е. вызовы в неуправляемый код, такой как методы в компоненте COM или API ОС). Если вы сделаете вызов API, для которого требуется указатель на что-либо, CLR определит, когда он указывает на блок кучи, и автоматически закрепит этот блок.
Fikr bildirish
Так что CLR использует третий подход: выборочно предотвращает перемещение блоков кучи. Сборщик мусора может свободно работать во время операций ввода-вывода, но некоторые блоки кучи могут быть закреплены. Закрепление блока устанавливает флаг, который сообщает сборщику, что блок в настоящее время не может быть перемещен. Таким образом, если сборщик мусора встретит такой блок, он просто оставит его на месте, но попытается переместить все вокруг него.
Fikr bildirish
Уплотнение кучи (heap compaction) — важная функция сборщика мусора CLR, поскольку она оказывает сильное влияние на производительность. Некоторые операции могут предотвратить уплотнение, и это то, чего мы хотели бы избежать, потому что фрагментация может увеличить использование памяти и значительно снизить производительность.
Fikr bildirish
Можно попросить .NET запретить сборку мусора во время выполнения определенного раздела кода. Это полезно, если вы выполняете задачу, чувствительную ко времени. Windows, macOS и Linux не являются ОС реального времени, поэтому никаких гарантий быть не может, но временное выключение сборщиков мусора в критические моменты может тем не менее оказаться полезным для снижения вероятности того, что все замедлится в самый нужный момент. Имейте в виду, что этот механизм работает, передвигая вперед любую работу сборщика мусора, которая в противном случае произошла бы в соответствующем разделе кода, поэтому это может привести к более ранним задержкам, связанным со сборкой мусора. Это лишь гарантирует, что после того, как обозначенная область кода начнет работать, и если выполняются определенные требования, больше не будет происходить сборок мусора. По сути, задержки устраняются прежде, чем начинается чувствительная ко времени работа.
Fikr bildirish
С режимом сервера могут возникнуть кое-какие проблемы. Этот режим работает лучше всего, когда его использует только один процесс, поскольку он настроен на одновременное использование во время сборок всех ядер ЦП. Он также имеет тенденцию потреблять значительно больше памяти, чем режим рабочей станции. Если на одном сервере запущено несколько процессов .NET, которые это делают, борьба за ресурсы может снизить производительность. Другая проблема со сборкой мусора сервера заключается в том, что она отдает предпочтение производительности, а не времени ответа.
Fikr bildirish
Режим сервера существенно отличается от режима рабочей станции. Он доступен только при наличии нескольких аппаратных потоков, например в случае многоядерного процессора или нескольких физических процессоров. (Если вы включили сборку мусора сервера, но ваш код в конечном итоге выполняется на одноядерном компьютере, он вернется к использованию сборки мусора рабочей станции.)
Fikr bildirish
Неконкурентный режим предназначен для оптимизации пропускной способности на одном процессоре с одним ядром. Он может оказаться более эффективным, потому что в обмен на меньшие задержки фоновая сборка мусора использует немного больше памяти и больше циклов ЦП для любой конкретной задачи, чем непараллельная сборка мусора. В некоторых задачах ваш код может работать быстрее, если отключить ее, установив для свойства ConcurrentGarbageCollection значение false в файле проекта
Fikr bildirish
Проблема в полных сборках, и именно их фоновый режим обрабатывает по-другому. Не вся работа, выполняемая при сборке, действительно требует приостановки всего, и фоновый режим использует это, позволяя полной (поколение 2) сборке продолжать работу в фоновом потоке, не блокируя другие потоки до окончания сборки. Это может позволить машинам с несколькими процессорными ядрами (большинство компьютеров в настоящее время) выполнять полные сборки мусора на одном ядре, в то время как другие ядра продолжают полезную работу. Это особенно полезно в приложениях с пользовательским интерфейсом, поскольку снижает вероятность того, что приложение перестает отвечать на запросы из-за сборок мусора.
Fikr bildirish
Существуют определенные фазы сборки мусора, во время которых CLR вынужден приостановить выполнение для обеспечения согласованности. При сборке из эфемерных поколений потоки будут приостановлены для большинства операций. Обычно это безболезненно, потому что эти сборки, как правило, работают очень быстро — они занимают столько же времени, сколько ошибка страницы памяти, которая не приводит к работе с диском. (Такие неблокирующие ошибки страницы памяти происходят довольно часто и настолько быстро, что многие разработчики, похоже, даже не подозревают, что они вообще случаются.)
Fikr bildirish