C# Cooking
132 subscribers
42 photos
50 videos
70 links
Просветительский канал по языку C# CSharpCooking.github.io
Download Telegram
Вопрос:
Что такое интернирование строк?
Ответ:
Интернирование строк – это процесс сохранения одной копии каждой уникальной строки для уменьшения использования памяти. Этот процесс реализован в .NET Framework с использованием строкового пула интернирования (String Intern Pool).
Когда строка интернируется, проверяется наличие этой строки в пуле интернирования. Если строка уже есть в пуле, возвращается ссылка на строку из пула, а не создается новый экземпляр строки. Если строки нет в пуле, она добавляется туда, и возвращается ссылка на новый экземпляр строки.
Пример:
string str1 = "Hello, World!";
string str2 = string.Intern("Hello, World!");
Console.WriteLine(object.ReferenceEquals(str1, str2)); // Выведет "True"
В этом примере, даже если "Hello, World!" был создан дважды, обе переменные str1 и str2 ссылаются на один и тот же экземпляр строки в памяти благодаря интернированию.
Тем не менее, стоит помнить, что не все строки автоматически интернируются в .NET. Литералы строк в исходном коде автоматически интернируются, но динамически созданные строки – нет, если только вы явно не вызовете метод string.Intern().
Интернирование может быть полезным, когда работают с большим количеством повторяющихся строк, чтобы оптимизировать использование памяти. Однако оно может быть неэффективным при работе со строками, которые редко повторяются.

#интернированиестрок #программирование #сишарп #stringintern #csharp #csharpdotnet #csharpprogramming
👍2
Инфраструктура PLINQ, класс Parallel и объекты Task автоматически маршализируют исключения потребителю, то есть исключения автоматически перехватываются и повторно генерируются для вызывающего потока. Но, к сожалению, дело не сводится просто к перехвату DivideByZeroException. Поскольку параллельные библиотеки задействуют множество потоков, вполне возможна одновременная генерация двух и более исключений. Чтобы обеспечить получение сведений обо всех исключениях, по указанной причине исключения помещаются в контейнер AggregateException, свойство InnerExceptions которого содержит каждое из перехваченных исключений.

Как инфраструктура PLINQ, так и класс Parallel при обнаружении первого исключения заканчивают выполнение запроса или цикла, не обрабатывая любые последующие элементы либо итерации тела цикла. Однако до завершения текущей итерации цикла могут быть сгенерированы дополнительные исключения. Первое возникшее исключение в AggregateException доступно через свойство InnerException.

#aggregateexception #параллельноепрограммирование #сишарп #taskfactory #parallelprogramming #csharp #csharpdotnet #csharpprogramming
👍1
Параллелизм задач | Параллельное программирование
https://youtu.be/98Hyw6Xjn6o

#ПараллельноеПрограммирование #ПараллелизмЗадач
👍1
AggregateException часто содержит другие AggregateException. Например, когда дочерняя задача генерирует исключение. Чтобы упростить обработку, можно устранить вложенность, вызвав Flatten. Данный метод возвращает новый объект AggregateException с плоским списком внутренних исключений. Это позволяет избежать перебора вложенных AggregateException и упрощает код обработки ошибок из параллельных операций.

#flatten #aggregateexception #обработкаисключений #параллельныевычисления #csharp
👍1
КОЛЛЕКЦИИ ПРОИЗВОДИТЕЛЕЙ/ПОТРЕБИТЕЛЕЙ В C#

🔹 Производитель: добавление элемента.
🔹 Потребитель: извлечение с удалением.

📌 IProducerConsumerCollection: потокобезопасная коллекция.
🔸 Реализации: ConcurrentStack, ConcurrentQueue, ConcurrentBag.

🔍 Основные методы:
- CopyTo: копирование коллекции.
- ToArray: преобразование в массив.
- TryAdd: попытка добавления.
- TryTake: попытка извлечения.

Атомарность: проверка + действие без блокировки.

🚀 TryTake: какой элемент извлекается?
- Стек: последний добавленный.
- Очередь: первый добавленный.
- Пакет: наиболее эффективный для удаления.

#Programming #ConcurrentProgramming #Multithreading #DotNet #CSharp #Coding #SoftwareDevelopment #Concurrency #DataStructures #Developer #CodingLife #SoftwareEngineering #Algorithms #DataSynchronization #ComputerScience #Tech #DeveloperCommunity #Code #LearningToCode #DeveloperTools #ProgrammingTips #CodingKnowledge #TechWorld #Technology #Innovation
👍1
🔥 ConcurrentBag в действии!

Работает как связанный список связанных списков.
Метод Add пакета не допускает почти никаких состязаний, когда вызывается многими потоками одновременно.
Параллельные пакеты идеальны, когда количество вызовов Add и Таке сбалансировано в рамках потока.

🔍 Внутренняя кухня:
- Каждый поток имеет свой закрытый список.
- Извлечение происходит либо с "головы" своего списка, либо достигается "воровством" с "хвоста" другого.

📌 Важные моменты реализации:
- если поток добавляет элемент в свой закрытый список с числом элементов меньше двух, то накладывается блокировка на список, так как другой поток в это время может забирать данные текущего потока (stealing thread);
- если поток забирает элемент закрытого списка другого потока, то он забирает его не с "головы", а с "хвоста", то есть если в списке более двух элементов, то поток может заимствовать элемент без блокировки данного списка (в таком случае невозможно "состояние гонки", так как между добавляемым и забираемым элементом есть как минимум один промежуточный).

#ConcurrentBag #Multithreading #ParallelProgramming #ConcurrentCollections #LockFree #ThreadSafety #ProgrammingTips #DataStructures #Concurrency #ParallelQueue #ParallelStack #AddMethod #TakeMethod #ThreadStealing #RaceCondition #LinkedLists
👍1
🚀 BlockingCollection<T> в C#!

🔒 Всем, кто работает с многопоточными приложениями в .NET, знакома ситуация, когда методы вроде TryTake возвращают false на пустой коллекции. Часто бывает необходимо организовать ожидание, пока элемент не станет доступным. Для решения этой задачи в C# существует класс BlockingCollection<T>.

💡 Что делает BlockingCollection?
- BlockingCollection<T> оборачивает любую коллекцию, реализующую IProducerConsumerCollection<T>.
- Предоставляет блокирующие методы Take и Add, удобные в многопоточной среде.
- Позволяет ограничить размер коллекции, блокируя добавление новых элементов при достижении предела.

🔧 Как использовать?
1️. Создайте экземпляр, указав тип коллекции и максимальный размер.
2️. Используйте Add или TryAdd для добавления элементов.
3️. Используйте Take или TryTake для извлечения элементов.
- По умолчанию используется ConcurrentQueue<T>.
- Методы Add и Take могут блокироваться в зависимости от состояния коллекции.

🔄 Дополнительные возможности:
- GetConsumingEnumerable предлагает элегантный способ потребления элементов в бесконечном цикле.
- CompleteAdding закрывает коллекцию для добавления новых элементов.
- AddToAny и TakeFromAny позволяют работать сразу с несколькими блокирующими коллекциями.

🔑 Ключ к многопоточной эффективности:
BlockingCollection<T> идеально подходит для сценариев, где нужна гибкая и надежная синхронизация между производящими и потребляющими потоками.

#Multithreading #ConcurrentCollections #DotNetCore #AsyncProgramming #CSharpProgramming #CodingLife #DeveloperTools #SoftwareEngineering #TechCommunity #ProgrammingTips #CodeNewbies #TechWorld #SoftwareDevelopment
👍1
Очередь производителей/потребителей – структура, полезная как при параллельном программировании, так и в общих сценариях параллелизма. Ниже описаны основные аспекты ее работы.
• Очередь настраивается для описания элементов работы или данных, над которыми выполняется работа.
• Когда задача должна выполниться, она ставится в очередь, а вызывающий код занимается другой работой.
• Один или большее число рабочих потоков функционируют в фоновом режиме, извлекая и запуская элементы из очереди.

Очередь производителей/потребителей обеспечивает точный контроль над тем, сколько рабочих потоков выполняется за раз, что полезно для ограничения эксплуатации не только ЦП, но также и других ресурсов. Скажем, если задачи выполняют интенсивные операции дискового ввода-вывода, то можно ограничить параллелизм, не истощая операционную систему и другие приложения. На протяжении времени жизни очереди можно также динамически добавлять и удалять рабочие потоки. Пул потоков CLR сам представляет собой разновидность очереди производителей/потребителей, которая оптимизирована для кратко выполняющихся заданий с интенсивными вычислениями.

Очередь производителей/потребителей обычно хранит элементы данных, на которых выполняется (одна и та же) задача. Например, элементами данных могут быть имена файлов, а задача может осуществлять шифрование содержимого таких файлов. С другой стороны, применяя делегаты в качестве элементов, можно построить более универсальную очередь производителей/потребителей, где каждый элемент способен делать все что угодно.

Реализовать очередь производителей/потребителей можно, используя событие AutoResetEvent (а также впоследствии методы Wait и Pulse класса Monitor). Тем не менее, написание очереди производителей/потребителей с нуля стало необязательным, т.к. большая часть функциональности предлагается классом BlockingCollection<T>. На слайде продемонстрировано, как его задействовать.

#ParallelProgramming #ConcurrencyControl #ProducerConsumerQueue #ThreadManagement #CodingLife
👍1