Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
178 0 18:04, 26-08-2023Книга Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен читать онлайн бесплатно без регистрации
В 10-м издании книги описаны новейшие возможности языка C# 9 и .NET 5 вместе с подробным "закулисным" обсуждением, призванным расширить навыки критического мышления разработчиков, когда речь идет об их ремесле. Книга охватывает ASP.NET Core, Entity Framework Core и многое другое наряду с последними обновлениями унифицированной платформы .NET, начиная с улучшений показателей производительности настольных приложений Windows в .NET 5 и обновления инструментария XAML и заканчивая расширенным рассмотрением файлов данных и способов обработки данных. Все примеры кода были переписаны с учетом возможностей последнего выпуска C# 9.
Ради доказательства сделанных утверждений предположим, что метод Printer.PrintNumbers() необходимо вызвать во вторичном потоке, который должен вести себя как фоновый. Это означает, что метод, указываемый типом Thread (через делегат ThreadStart или ParametrizedThreadStart), должен обладать возможностью безопасного останова, как только все потоки переднего плана закончат свою работу. Конфигурирование такого потока сводится просто к установке свойства IsBackground в true:
Console.WriteLine("***** Background Threads *****n");
Printer p = new Printer();
Thread bgroundThread =
new Thread(new ThreadStart(p.PrintNumbers));
// Теперь это фоновый поток.
bgroundThread.IsBackground = true;
bgroundThread.Start();
Обратите внимание, что в приведенном выше коде не делается вызов Console.ReadLine(), чтобы заставить окно консоли оставаться видимым, пока не будет нажата клавиша <Enter>. Таким образом, после запуска приложение немедленно прекращается, потому что объект Thread сконфигурирован как фоновый поток. С учетом того, что точка входа приложения (приведенные здесь операторы верхнего уровня или метод Main()) инициирует создание первичного потока переднего плана, как только логика в точке входа завершится, домен приложения будет выгружен, прежде чем вторичный поток сможет закончить свою работу.
Однако если закомментировать строку, которая устанавливает свойство IsBackground в true, то обнаружится, что на консоль выводятся все числа, поскольку все потоки переднего плана должны завершить свою работу перед тем, как домен приложения будет выгружен из обслуживающего процесса.
По большей части конфигурировать поток для функционирования в фоновом режиме может быть удобно, когда интересующий рабочий поток выполняет некритичную задачу, потребность в которой исчезает после завершения главной задачи программы. Например, можно было бы построить приложение, которое проверяет почтовый сервер каждые несколько минут на предмет поступления новых сообщений электронной почты, обновляет текущий прогноз погоды или решает какие-то другие некритичные задачи.
Проблема параллелизма
При построении многопоточных приложений необходимо гарантировать, что любой фрагмент разделяемых данных защищен от возможности изменения со стороны сразу нескольких потоков. Поскольку все потоки в домене приложения имеют параллельный доступ к разделяемым данным приложения, вообразите, что может произойти, если множество потоков одновременно обратятся к одному и тому же элементу данных. Так как планировщик потоков случайным образом приостанавливает их работу, что если поток А будет вытеснен до завершения своей работы? Тогда поток В прочитает нестабильные данные.
Чтобы проиллюстрировать проблему, связанную с параллелизмом, давайте создадим еще один проект консольного приложения под названием MultiThreadedPrinting. В приложении снова будет использоваться построенный ранее класс Printer, но на этот раз метод PrintNumbers() приостановит текущий поток на сгенерированный случайным образом период времени.
using System;
using System.Threading;
namespace MultiThreadedPrinting
{
public class Printer
{
public void PrintNumbers()
{
// Отобразить информацию о потоке.
Console.WriteLine("-> {0} is executing PrintNumbers()",
Thread.CurrentThread.Name);
// Вывести числа.
for (int i = 0; i < 10; i++)
{
// Приостановить поток на случайный период времени.
Random r = new Random();
Thread.Sleep(1000 * r.Next(5));
Console.Write("{0}, ", i);
}
Console.WriteLine();
}
}
}
Вызывающий код отвечает за создание массива из десяти (уникально именованных) объектов Thread, каждый из которых вызывает метод одного и того же экземпляра класса Printer:
using System;
using System.Threading;
using MultiThreadedPrinting;
Console.WriteLine("*****Synchronizing Threads *****n");
Printer p = new Printer();
// Создать 10 потоков, которые указывают на один.
// и тот же метод того же самого объекта
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++)
{
threads[i] = new Thread(new ThreadStart(p.PrintNumbers))
{
Name = $"Worker thread #{i}"
};
}
// Теперь запустить их все.
foreach (Thread t in threads)
{
t.Start();
}
Console.ReadLine();
Прежде чем взглянуть на тестовые запуски, кратко повторим суть проблемы. Первичный поток внутри этого домена приложения начинает свое существование с порождения десяти вторичных рабочих потоков. Каждому рабочему потоку указывается на необходимость вызова метода PrintNumbers() того же самого экземпляра класса Printer. Поскольку никаких мер для блокировки разделяемых ресурсов данного объекта (консоли) не предпринималось, есть неплохой шанс, что текущий поток будет вытеснен до того, как метод PrintNumbers() выведет полные результаты. Из-за того, что не известно в точности, когда подобное может произойти (если вообще произойдет), будут получены непредсказуемые результаты. Например, вывод может выглядеть так:
*****Synchronizing Threads *****
-> Worker thread #3 is executing PrintNumbers()
-> Worker thread #0 is executing PrintNumbers()
-> Worker thread #1 is executing PrintNumbers()
-> Worker thread #2 is executing PrintNumbers()
-> Worker thread #4 is executing PrintNumbers()
-> Worker thread #5 is executing PrintNumbers()
-> Worker thread #6 is executing PrintNumbers()
-> Worker thread #7 is executing PrintNumbers()
-> Worker thread #8 is executing PrintNumbers()
-> Worker thread #9 is executing PrintNumbers()
0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 2, 3, 1, 2, 2, 2, 1, 2,
1, 1, 2, 2, 3, 3, 4,
3, 3, 2, 2, 3, 4, 3, 4, 5, 4, 5, 4, 4, 3, 6, 7, 2, 3, 4, 4, 4, 5, 6, 5,
3, 5, 8, 9,
6, 7, 4, 5, 6, 6, 5, 5, 5, 8, 5, 6, 7, 8, 7, 7, 6, 6, 6, 8, 9,
8, 7, 7, 7, 7, 9,
6, 8, 9,
8, 9,
9, 9,
8, 8, 7, 8, 9,
9,
9,
Запустите приложение еще несколько раз. Скорее всего, каждый раз вы будете получать отличающийся вывод.
На заметку! Если получить непредсказуемый вывод не удается, увеличьте количество потоков с 10 до 100 (например) или добавьте в код еще один вызов Thread.Sleep(). В конце концов, вы столкнетесь с проблемой параллелизма.
Должно быть совершенно ясно, что здесь присутствуют
Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор LoveRead.info.
Оставить комментарий
-
Борис14 июнь 00:50
Колокола в России тем и отличались от западных что раскачиаали именно язык колокола,а не сам колокол! Авторы что-жертвы ЕГЭ? Не...
Соединенные Штаты России 3 - Полина Ром
-
Людмила Хофман10 июнь 22:13
У меня перевернулся мир после прочтения ваших книг! Так приятно и чисто на душе, ведь по сути неважно кто с кем , а только любовь...
Долгая игра - Рейчел Рид
-
Анна08 июнь 11:28
Спасибо за новую историю жизни и любви на сайте,прочитала с удовольствием ....
Давай поженимся - Юлия Резник
