Консольний додаток, microsoft docs
вступ
Це керівництво розкриє для вас деякі можливості .NET Core і мови C #. Ви познайомитеся з наступними аспектами:
- робота з інтерфейсом командного рядка (CLI) в .NET Core;
- структура консольного застосування C #;
- консольне введення-виведення;
- основні відомості про інтерфейси API файлового введення-виведення в .NET Core;
- основні відомості про модель асинхронного програмування задач в .NET Core.
У цьому керівництві описано безліч функцій. Давайте почнемо по черзі розбирати їх.
попередні вимоги
створення програми
Першим кроком є створення нового додатка. Відкрийте командний рядок і створіть новий каталог для програми. Перейдіть в цей каталог. У командному рядку введіть команду dotnet new console. Ця команда створює початковий набір файлів для базового програми Hello World.
Перш ніж вносити зміни в цей додаток, давайте розберемо процедуру його запуску. Коли ви створите додаток, наберіть у командному рядку команду dotnet restore. Вона запускає процес відновлення з пакета NuGet. NuGet є диспетчер пакетів для .NET. Ця команда завантажує всі відсутні залежності для проекту. Оскільки ми маємо справу з новим проектом, для нього поки не існує залежностей, тому при першому запуску буде завантажена тільки платформа .NET Core. Після цього першого запуску команду dotnet restore потрібно буде запускати тільки після додавання нових залежних пакетів або при оновленні версій використовуваних залежностей. Цей процес також створює файл блокування проекту (project.lock.json) в каталозі проекту. Цей файл допомагає керувати залежностями проекту. Він вказує локальне розташування всіх залежностей проекту. Цей файл не обов'язково поміщати в систему управління версіями. Він буде автоматично створений при виконанні команди dotnet restore.
Коли завершиться відновлення пакетів, запустіть dotnet build. Ця команда запускає підсистему збирання і створює виконуваний файл програми. Тепер можна виконати команду dotnet run. яка запустить вашу програму.
Ця інструкція вказує компілятору, що в області дії знаходяться всі типи з простору імен System. Як і інші об'єктно орієнтовані мови, з якими ви могли працювати раніше, C # використовує простору імен для організації типів. У нашій програмі Hello World все точно так же. Як ви бачите, програма укладена в простір імен ConsoleApplication. Це не дуже зрозуміле ім'я, давайте змінимо його на TeleprompterConsole:
Читання і висновок файлу
Перша функція, яку ми додамо, буде зчитувати дані з текстового файлу і виводити отриманий текст в консоль. Спочатку нам потрібно додати текстовий файл. Скопіюйте в каталог проекту файл sampleQuotes.txt зі сховищ GitHub для цього прикладу. Він буде джерелом тексту для вашого застосування. Щоб завантажити приклад програми для цього розділу, скористайтеся інструкціями в розділі Приклади і керівництва.
Тепер додайте в клас Program (він розташований відразу за методом Main) наступний метод:
Цей метод використовує типи з двох нових просторів імен. Щоб така програма успішно скомпілювати, потрібно додати в початок файлу наступні два рядки:
інтерфейс IEnumerable
Цей метод є спеціалізованим підтипом стандартного методу перечіслітеля C #. Метод перечіслітеля повертає послідовності, для яких застосовується відкладене обчислення. Це означає, що кожен елемент в послідовності створюється тільки в той момент, коли до нього виконується звернення до коді обробки послідовності. Методи перечіслітеля містять одну або кілька інструкцій yield return. Що повертається методом ReadFrom об'єкт містить код для створення кожного елемента послідовності. У нашому прикладі він Новомосковскет наступний рядок тексту з вихідного файлу і повертає цей рядок. Кожен раз, коли викликає код запитує наступний елемент з послідовності, код зчитує з файлу і повертає наступний рядок тексту. Коли файл закінчиться, послідовність повідомляє, що в ній більше немає елементів.
Тут використовуються ще два елементи синтаксису C #, які можуть бути для вас новими. Інструкція using в цьому методі управляє звільненням ресурсів. Змінна, яка ініціалізується в інструкції using (в нашому прикладі це reader) повинна реалізовувати інтерфейс IDisposable. Інтерфейс IDisposable визначає єдиний метод (Dispose), який викликається для звільнення ресурсу. Компілятор створює такий виклик, коли виконання коду досягає закриває дужки інструкції using. Створений компілятором код гарантує звільнення ресурсу навіть у тому випадку, якщо в блоці коду, визначеному інструкцією using, буде створено виняток.
Мінлива reader визначена з ключовим словом var. Ключове слово var визначає неявно типізовану локальну змінну. Це означає, що тип змінної визначається під час компіляції по типу об'єкта, присвоєного цієї змінної. Тут у змінній зберігається об'єкт StreamReader. що повертається методом @ System.IO.File.OpenText.
Тепер давайте створимо в методі Main код для читання файлу:
Запустіть програму командою dotnet run і переконайтеся, що всі текстові рядки виводяться в консоль.
Додавання затримок і форматування вихідних даних
У цьому розділі описані два дії. По-перше, поновіть метод ітератора, щоб він повертав не всю рядок цілком, а кожне слово окремо. Для цього внесіть такі зміни. Замініть інструкцію yield return line; наступним кодом:
Тепер слід змінити код обробки рядків файлу, додавши затримку після виведення кожного слова. Замініть інструкцію Console.WriteLine (line) в методі Main на такий блок коду:
Клас Task знаходиться в простору імен System.Threading.Tasks. тому цю інструкцію using потрібно додати в верхній частині файлу:
Тепер додайте наступний код після інструкції yield return word + ""; (Перед закриваючою фігурною дужкою):
асинхронні завдання
І на останньому етапі ми додамо код, який буде виконувати дві асинхронні завдання, одна з яких здійснює висновок тексту, а друга чекає введення від користувача для прискорення або уповільнення виведення тексту. Цей етап поділяється на кілька кроків, по завершенні яких ви отримаєте всі необхідні оновлення. Першим кроком є створення асинхронної завдання (@ System.Threading.Tasks.Task), яка повертає метод з тим кодом, який ви створили раніше для читання і відображення файлу.
Додайте наступний метод в клас Program. Цей текст заснований на тексті методу Main:
Але ви можете помітити два зміни. По-перше, в тексті немає виклику Wait (). який в синхронному режимі очікує завершення завдання. Замість нього в цій версії використовується ключове слово await. Щоб це працювало, в сигнатуру методу потрібно додати модифікатор async. Цей метод повертає Task. Зверніть увагу, що тут немає інструкції для повернення об'єкта Task. Замість цього об'єкт Task створюється в коді, який компілятор надає в точці використання оператора await. Уявіть, що метод завершує виконання при досягненні await. Він повертає Task в знак того, що робота ще не завершена. Метод відновить свою роботу, коли завершиться очікувана завдання. Коли робота методу завершиться, це буде відображено в повернутому об'єкті Task. Зухвалий код може відстежувати стан отриманого Task. щоб визначити момент завершення методу.
Тепер наш новий метод можна викликати з методу Main:
Тут, в методі Main. код синхронно очікує завершення. Завжди, коли це можливо, слід використовувати оператор await замість синхронного очікування. Але в методі Main консольного застосування заборонено використовувати оператор await. В іншому випадку додаток завершить роботу раніше, ніж виконає всі свої завдання.
Тут створюється лямбда-вираз, що представляє делегат Action. який зчитує натискання клавіші з консолі і змінює локальну змінну з тривалістю затримки в тому випадку, якщо користувач натиснув клавішу "<" или ">". Цей метод використовує метод ReadKey (). Щоб блокувати виконання і очікувати натискання клавіші.
Щоб завершити створення цієї функції, нам потрібна нова інструкція async Task. яка поверне метод, що запускає обидва завдання (GetInput і ShowTeleprompter) і керуючий обміном даними між цими завданнями.
Помістіть цей клас в окремий новий файл і укладіть в простір імен TeleprompterConsole. як показано вище. Також слід додати інструкцію using static. щоб використовувати посилання на методи Min і Max без вказівки імені зовнішнього класу або простору імен. Інструкція using static імпортує всі методи з одного класу. У цьому вона відрізняється від використаної раніше інструкції using. яка імпортує всі класи з простору імен.
Ще одна нова для вас функція мови - це інструкція lock. Вона гарантує, що в цьому коді в будь-який момент може виконуватися тільки один потік. Якщо будь-який з потоків виконує заблокований розділ, все решта потоки повинні очікувати, поки він не вийде з цього розділу. Інструкція lock використовує об'єкт, який захищає заблокований розділ. Цей клас відповідає стандартним принципом блокування приватного об'єкта в межах класу.
Тепер вам потрібно оновити методи ShowTeleprompter і GetInput для використання нового об'єкта config. І ще одна інструкція Task. яка повертає метод async. запускає обидва завдання і завершальний роботу після закінчення першого завдання:
Тут ми використовуємо виклик нового методу WhenAny (Task []). Цей метод створює завдання (Task), яка завершується відразу, як тільки завершиться будь-яка із завдань в списку аргументів.
Тепер вам потрібно оновити методи ShowTeleprompter і GetInput. щоб вони використовували об'єкт config для затримки:
Нова версія методу ShowTeleprompter викликає новий метод з класу TeleprompterConfig. Зараз потрібно змінити метод Main. щоб замість ShowTeleprompter він викликав RunTeleprompter:
І нарешті, додайте в клас TelePrompterConfig метод SetDone і властивість Done:
висновок
У цьому підручнику ми продемонстрували вам ряд функцій мови C # і бібліотек .NET Core, пов'язаних з роботою в консольних додатках. На основі отриманих знань ви зможете розвивати свої уявлення про мову і представлених тут класах. Ви побачили базові приклади використання файлового і консольного вводу-виводу, асинхронного програмування на основі завдань з блокуванням і без блокування. Ви отримали інформацію про мову C #, структурі програм на C #, а також про інтерфейс командного рядка і засобах .NET Core.