Вопрос:
Как задействовать статическое событие
Ответ:
Необработанные исключения в автономных задачах называются необнаруженными исключениями, и среда CLR будет повторно генерировать исключение в потоке финализаторов, когда объект задачи покидает область видимости и обрабатывается сборщиком мусора).
Ниже пример, который показывает, как можно использовать
Для справки:
- Метод
- Метод
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
Как задействовать статическое событие
TaskScheduler.UnobservedTaskException
в сценарии использования задач с необработанными исключениями?Ответ:
Необработанные исключения в автономных задачах называются необнаруженными исключениями, и среда CLR будет повторно генерировать исключение в потоке финализаторов, когда объект задачи покидает область видимости и обрабатывается сборщиком мусора).
TaskScheduler.UnobservedTaskException
– это событие, которое срабатывает, когда задача, завершившаяся с исключением, была собрана сборщиком мусора, не будучи обработанной. Это может быть полезно для перехвата и обработки исключений, которые не были явно обработаны в коде.Ниже пример, который показывает, как можно использовать
TaskScheduler.UnobservedTaskException
в сценарии с задачами:using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// Подписка на событие UnobservedTaskException
TaskScheduler.UnobservedTaskException += (sender, e) =>
{
Console.WriteLine("Необработанное исключение в задаче:");
e.SetObserved(); // Помечаем исключение как обработанное
foreach (var ex in e.Exception.InnerExceptions)
{
Console.WriteLine(" - " + ex.Message);
}
};
// Создание задачи, которая завершается с исключением
var task = Task.Run(() =>
{
throw new Exception("Исключение в задаче");
});
// Задача-продолжение, которая также генерирует исключение
var continuation = task.ContinueWith(t =>
{
throw new Exception("Исключение в продолжении задачи");
});
// Ждем некоторое время, чтобы задачи завершились
Thread.Sleep(1000);
// Выполнение сборки мусора для того, чтобы событие UnobservedTaskException сработало
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Завершение программы.");
}
}
В этом примере создаются две задачи, обе из которых генерируют исключения. Затем явно вызывается сборка мусора (GC.Collect
и GC.WaitForPendingFinalizers
), чтобы поток финализаторов вызвал событие TaskScheduler.UnobservedTaskException
для исключений, которые не были обработаны.Для справки:
- Метод
GC.Collect
явно инициирует процесс сборки мусора. Это означает, что сборщик мусора пытается освободить память, удаляя объекты, которые больше не доступны (т.е. на которые нет ссылок). Обычно не рекомендуется вызывать этот метод вручную, потому что сборщик мусора в .NET достаточно эффективен и оптимизирован для работы в различных сценариях. Однако, в некоторых специальных случаях, когда вы точно знаете, что это может быть полезно (например, перед большими вычислениями), можно использовать явное взаимодействие со сборщиком мусора.- Метод
GC.WaitForPendingFinalizers
приостанавливает выполнение текущего потока до тех пор, пока сборщик мусора не завершит выполнение всех финализаторов. Финализатор – это специальный метод, который выполняется перед уничтожением объекта, и обычно используется для освобождения неуправляемых ресурсов. Этот вызов полезен в сценариях, где вам необходимо убедиться, что все финализируемые объекты были очищены перед продолжением выполнения кода. Как и с GC.Collect
, это не что-то, что следует делать часто, и должно использоваться с осторожностью.#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
Мощная особенность продолжений связана с тем, что они запускаются, только когда завершены все дочерние задачи. В этой точке любые исключения, сгенерированные дочерними задачами, маршализируются в продолжение.
В примере на слайде мы начинаем три дочерние задачи, каждая из которых генерирует исключение NullReferenceException. Затем мы перехватываем все исключения сразу через продолжение на родительской задаче.
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
В примере на слайде мы начинаем три дочерние задачи, каждая из которых генерирует исключение NullReferenceException. Затем мы перехватываем все исключения сразу через продолжение на родительской задаче.
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
Расширяющий метод “поглощает” необработанные исключения задачи. Метод может быть улучшен добавлением кода для регистрации исключения.
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
This media is not supported in your browser
VIEW IN TELEGRAM
Параллелизм задач. Расширяющий метод, продолжение и дочерние задачи.
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
Важно понимать, что когда продолжение не выполнилось из-за упомянутых флагов, оно не забыто и не отброшено – это продолжение отменено. Например, взгляните на приведенный на втором слайде код. Несложно заметить, что задача
Если нужно, чтобы задача
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
t3
всегда будет запланирована – даже если t1
не генерирует исключение. Причина в том, что если задача t1
завершена успешно, тогда задача fault
будет отменена, и с учетом отсутствия ограничений продолжения задача t3
будет запущена безусловным образом.Если нужно, чтобы задача
t3
выполнялась, только если действительно была запущена задача fault
, то потребуется поступить так:Task t3 = fault.ContinueWith (ant => Console.WriteLine ("t3"), TaskContinuationOptions.NotOnCanceled);(В качестве альтернативы мы могли бы указать
OnlyOnRanToCompletion
; разница в том, что тогда задача t3
не запустилась бы в случае генерации исключения внутри задачи fault
.)#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
This media is not supported in your browser
VIEW IN TELEGRAM
Параллелизм задач. Условные продолжения.
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
#программирование #сишарп #csharp #csharpdotnet #csharpprogramming
С помощью методов
#параллелизмзадач #программирование #сишарп #taskparallelism #csharp #csharpdotnet #csharpprogramming
ContinueWhenAll
и ContinueWhenAny
класса TaskFactory
выполнение продолжения можно планировать на основе завершения множества предшествующих задач. Однако эти методы стали избыточными после появления комбинаторов задач (WhenAll
и WhenAny
).#параллелизмзадач #программирование #сишарп #taskparallelism #csharp #csharpdotnet #csharpprogramming
Вызов
#параллелизмзадач #программирование #сишарп #taskparallelism #csharp #csharpdotnet #csharpprogramming
ContinueWith
более одного раза на той же самой задаче создает множество продолжений на единственном предшественнике. Когда предшественник завершается, все продолжения запускаются вместе (если только не было указано значение TaskContinuationOptions.ExecuteSynchronously
, эта опция заставляет продолжения выполняться последовательно в том же потоке, что и предшествующая задача). Код на слайде ожидает одну секунду, а затем выводит на консоль либо 'ABCD', либо 'BACD'.#параллелизмзадач #программирование #сишарп #taskparallelism #csharp #csharpdotnet #csharpprogramming
This media is not supported in your browser
VIEW IN TELEGRAM
Параллелизм задач. ContinueWhenAll,
ContinueWhenAny,
WhenAll, WhenAny.
#параллелизмзадач #программирование #сишарп #taskparallelism #csharp #csharpdotnet #csharpprogramming
ContinueWhenAny,
WhenAll, WhenAny.
#параллелизмзадач #программирование #сишарп #taskparallelism #csharp #csharpdotnet #csharpprogramming
Вопрос:
Можно ли назвать лямбда-выражение делегатом?
Ответ:
Лямбда-выражение и делегат – это разные понятия в C#:
– Делегат – это ссылочный тип, который ссылается на метод. Делегат объявляется отдельно с использованием ключевого слова
– Лямбда-выражение – это анонимный метод, который может быть использован для инициализации делегата. Лямбда объявляется в виде
Лямбда-выражение не является делегатом, но оно может быть преобразовано в делегат. Когда мы присваиваем лямбду делегату, компилятор автоматически компилирует лямбду в отдельный анонимный метод и создает экземпляр делегата, который ссылается на этот метод. Поэтому строго говоря нельзя утверждать, что "лямбда-выражение – это делегат". Лямбда просто используется для инициализации делегата.
#лямбдавыражение #делегат #программирование #сишарп #lambdaexpression #delegate #csharp #csharpdotnet #csharpprogramming
Можно ли назвать лямбда-выражение делегатом?
Ответ:
Лямбда-выражение и делегат – это разные понятия в C#:
– Делегат – это ссылочный тип, который ссылается на метод. Делегат объявляется отдельно с использованием ключевого слова
delegate
.– Лямбда-выражение – это анонимный метод, который может быть использован для инициализации делегата. Лямбда объявляется в виде
(input params) => {method body}
.Лямбда-выражение не является делегатом, но оно может быть преобразовано в делегат. Когда мы присваиваем лямбду делегату, компилятор автоматически компилирует лямбду в отдельный анонимный метод и создает экземпляр делегата, который ссылается на этот метод. Поэтому строго говоря нельзя утверждать, что "лямбда-выражение – это делегат". Лямбда просто используется для инициализации делегата.
#лямбдавыражение #делегат #программирование #сишарп #lambdaexpression #delegate #csharp #csharpdotnet #csharpprogramming
Media is too big
VIEW IN TELEGRAM
Параллелизм задач. Планировщик контекста синхронизации.
#планировщикзадач #контекстсинхронизации #программирование #сишарп #taskscheduler #synchronizationcontext #csharp #csharpdotnet #csharpprogramming
#планировщикзадач #контекстсинхронизации #программирование #сишарп #taskscheduler #synchronizationcontext #csharp #csharpdotnet #csharpprogramming
Media is too big
VIEW IN TELEGRAM
Параллелизм задач. Task.Factory.FromAsync.
#параллелизмзадач #программирование #сишарп #taskfactory #taskparallelism #csharp #csharpdotnet #csharpprogramming
#параллелизмзадач #программирование #сишарп #taskfactory #taskparallelism #csharp #csharpdotnet #csharpprogramming
Вопрос:
Что такое интернирование строк?
Ответ:
Интернирование строк – это процесс сохранения одной копии каждой уникальной строки для уменьшения использования памяти. Этот процесс реализован в .NET Framework с использованием строкового пула интернирования (String Intern Pool).
Когда строка интернируется, проверяется наличие этой строки в пуле интернирования. Если строка уже есть в пуле, возвращается ссылка на строку из пула, а не создается новый экземпляр строки. Если строки нет в пуле, она добавляется туда, и возвращается ссылка на новый экземпляр строки.
Пример:
Тем не менее, стоит помнить, что не все строки автоматически интернируются в .NET. Литералы строк в исходном коде автоматически интернируются, но динамически созданные строки – нет, если только вы явно не вызовете метод
Интернирование может быть полезным, когда работают с большим количеством повторяющихся строк, чтобы оптимизировать использование памяти. Однако оно может быть неэффективным при работе со строками, которые редко повторяются.
#интернированиестрок #программирование #сишарп #stringintern #csharp #csharpdotnet #csharpprogramming
Что такое интернирование строк?
Ответ:
Интернирование строк – это процесс сохранения одной копии каждой уникальной строки для уменьшения использования памяти. Этот процесс реализован в .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
Инфраструктура PLINQ, класс
Как инфраструктура PLINQ, так и класс
#aggregateexception #параллельноепрограммирование #сишарп #taskfactory #parallelprogramming #csharp #csharpdotnet #csharpprogramming
Parallel
и объекты Task
автоматически маршализируют исключения потребителю, то есть исключения автоматически перехватываются и повторно генерируются для вызывающего потока. Но, к сожалению, дело не сводится просто к перехвату DivideByZeroException
. Поскольку параллельные библиотеки задействуют множество потоков, вполне возможна одновременная генерация двух и более исключений. Чтобы обеспечить получение сведений обо всех исключениях, по указанной причине исключения помещаются в контейнер AggregateException
, свойство InnerExceptions
которого содержит каждое из перехваченных исключений. Как инфраструктура PLINQ, так и класс
Parallel
при обнаружении первого исключения заканчивают выполнение запроса или цикла, не обрабатывая любые последующие элементы либо итерации тела цикла. Однако до завершения текущей итерации цикла могут быть сгенерированы дополнительные исключения. Первое возникшее исключение в AggregateException
доступно через свойство InnerException
.#aggregateexception #параллельноепрограммирование #сишарп #taskfactory #parallelprogramming #csharp #csharpdotnet #csharpprogramming
This media is not supported in your browser
VIEW IN TELEGRAM
Параллелизм задач. Создание собственных фабрик задач.
#параллелизмзадач #программирование #сишарп #taskfactory #taskparallelism #csharp #csharpdotnet #csharpprogramming
#параллелизмзадач #программирование #сишарп #taskfactory #taskparallelism #csharp #csharpdotnet #csharpprogramming
Ошероув Р. Искусство автономного тестирования с примерами на C# https://csharpcooking.github.io/theory/RoyOsherove-The-Art-of-Unit-Testing.pdf
#программирование #сишарп #csharp #unittesting
#программирование #сишарп #csharp #unittesting
Трансляции по параллельному программированию
Темы: Parallel LINQ, параллелизм задач, параллельные коллекции.
https://csharpcooking.github.io/posts/Broadcasts-Parallel-Programming/
#сишарп #параллельноепрограммирование #csharp #parallelprogramming
Темы: Parallel LINQ, параллелизм задач, параллельные коллекции.
https://csharpcooking.github.io/posts/Broadcasts-Parallel-Programming/
#сишарп #параллельноепрограммирование #csharp #parallelprogramming
C# Cooking
Трансляции по параллельному программированию
Темы: Parallel LINQ, параллелизм задач, параллельные коллекции.