-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAsyncAndAwaitTask.txt
More file actions
88 lines (73 loc) · 6.72 KB
/
AsyncAndAwaitTask.txt
File metadata and controls
88 lines (73 loc) · 6.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
Название задачи: "Асинхронный загрузчик уровней с эмуляцией долгих операций (Async Level Loader)"
Контекст:
Ты разрабатывашь RPG. В игре есть проблема: при переходе между локациями
(например, из города в подземелье) игра "замерзает" на 2-3 секунды, пока загружаются данные.
Геймдизайнер сказал: "Сделай так, чтобы загрузка не блокировала игру,
а игрок видел анимированный прогресс-бар и мог даже открыть инвентарь во время загрузки (эмулируем)".
Твоя задача — создать прототип асинхронного загрузчика уровней в консоли.
Что нужно сделать:
1. Создай структуру данных для уровня (LevelData) — класс, который будет содержать:
- string LevelName (название уровня)
- int Width / int Height (размер карты)
- List<string> Enemies (список врагов на уровне)
- Dictionary<string, int> Resources (ресурсы на уровне: например, "золото" -> 100, "зелья" -> 5)
- Любые другие данные, которые захочется "загружать"
2. Создай класс LevelLoader:
- У него должен быть метод Task<LevelData> LoadLevelAsync(string levelName)
- Внутри метода эмулируй "долгую загрузку":
- Используй await Task.Delay(3000) — имитация загрузки с диска или из сети
- Создавай" данные уровня
(можно генерировать случайные врагов и ресурсы через Random — вспомни тему про генератор случайных чисел)
- Брось исключение с 20% вероятностью (Random), чтобы протестировать обработку ошибок — "файл уровня поврежден"
3. Создай класс Game:
- Он должен управлять текущим уровнем
- У него есть метод async Task LoadLevel(string levelName), который вызывает LevelLoader
- Во время загрузки (пока LoadLevelAsync выполняется) игра должна продолжать работать:
- Каждые 500 мс выводить в консоль анимированный индикатор загрузки: [#---] 25% и обновлять его
- Дать игроку возможность вводить команды
(например, "inventory" — показать инвентарь, "help" — список команд) во время загрузки
4. Реализуй обработку ошибок:
- Если LoadLevelAsync выбросил исключение (файл поврежден), игра должна:
- Перехватить исключение (try-catch)
- Вывести сообщение об ошибке красным цветом
- Предложить варианты: "R" — повторить загрузку, "M" — вернуться в меню (эмуляция),
любую другую клавишу — выход
- Не крашиться!
5. Используй CancellationToken (бонус, если хочешь прокачаться):
- Добавь возможность прервать загрузку, нажав клавишу "C" (cancel)
- Для этого нужно передавать CancellationToken в асинхронный метод
Требования к коду:
1. Используй async/await правильно — никаких .Result или .Wait(), которые блокируют поток
2. Обобщения (Generics) — например, можно сделать загрузчик не только для уровней, но и для других ресурсов
3. Делегаты и события — создай событие LevelLoaded в LevelLoader,
на которое подписывается Game, чтобы узнать, что уровень загружен
4. Обработка ошибок — обязательно try-catch в асинхронных методах
5. Коллекции — используй List, Dictionary для хранения данных уровня
Как должен выглядеть процесс:
Загрузка уровня "Темное подземелье"...
[#---] 25% (прошло 0.75 сек)
> inventory (игрок ввел команду во время загрузки)
Инвентарь: 5 зелий, 100 золота
[##--] 50% (прошло 1.5 сек)
> help
Доступные команды: inventory, cancel, status
[###-] 75% (прошло 2.25 сек)
> status
Загружается подземелье... подождите
[####] 100% (прошло 3 сек)
Уровень "Темное подземелье" загружен!
Враги: Скелет, Зомби, Паук
Ресурсы: золото: 250, зелья: 3
Нажмите любую клавишу для продолжения...
Бонус-задание (если будет легко):
1. Реализуй параллельную загрузку двух уровней одновременно (Task.WhenAll)
и объединение их данных (например, для сравнения).
2. Добавь прогресс-бар не просто с процентами, а с использованием символов и цвета.
3. Сделай так, чтобы прогресс обновлялся не равномерно, а скачками — как в реальной загрузке
(имитация чтения больших блоков данных).
Подсказки:
- Для асинхронного ввода команд можно использовать Task.WhenAny с задачами:
- LoadLevelAsync
- Task.Run(() => Console.ReadLine()) — но аккуратно, лучше использовать неблокирующий ввод
- Для отмены загрузки: создай CancellationTokenSource и передавай его токен в метод
- Для цвета в консоли: Console.ForegroundColor = ConsoleColor.Red;