Богдан Стефанюк

Заметки о программировании, путешествиях, плёнке и разных интересностях
Обо мне  •  Список заметок  •  Плёнка

Асинхронное программирование в C#

Небольшой конспект доклада об асинхронности в .NET. Cоветую его посмотреть, будет полезен как новичкам, так и уже опытным ребятам.

Что такое асинхронность?

Асинхронность — выполнение программного кода, не блокирующее потоки во время ожидания.

Например: делаем запрос в бд для получения некоторых данных.
У нас есть поток и запрос, который выполняет этот поток. При синхронном выполнении наш поток будет ждать, пока БД не ответит. В асинхронном случае наш поток будет выполнять другой запрос, пока БД обрабатывает текущий.

TAP

С приходом .NET Framework 4.0 появился новый способ для работы с асинхронностью — TAP. По сути, это набор классов, которые предоставляют более удобный интерфейс для работы с асинхронным кодом. Но мы всё ещё можем использовать старые подходы: APM и EAP. Но Майкрософт советует использовать TAP.

Центральным классов в TAP является Task. Он описывает отдельную задачу, выполнение которой может завершиться в какой-то момент. 

Детальнее про подходы работы с многопоточностью.

Как создать задачу?

Фреймворк предоставляет множество способов для создания и запуска задач, а также оборачивания старого кода (APM и EAP).

Фабрики запущенных задач

Task.Run(Action/Func)
Task.Factory.StartNew(Action/Func)

Фабрики завершенных задач

Task.FromResult(Result)
Task.FromCanceled(Result)
Task.FromException(Result)
Task.CompletedTask

Конструктор

var task = new Task(Action/Func)
task.Start()

Фабрики для оборачивания в таски

Task.Factory.FromAsync(APM pattern)
TaskCompletionSource(EAP, APM, etc)

Класс TaskScheduler

Класс, который содержит стратегию запуска и планирования задач Task. Существуют две стандартные реализации: ThreadPoolTaskScheduler и SynchronizationContextTaskScheduler. Первая запускает задачи с помощью пула потоков, а вторая — использует текущий контекст синхронизации.

Чтобы указать планировщику, что наша задача продолжительная мы можем использовать флаг TaskCreationOptions.LongRunning (указывается при создании задачи). Это гарантирует, что под нашу задачу выделиться отдельный поток и в него не будут планироваться продолжения других операций.

У каждого потока есть свой «текущий» контекст, который необязательно должен быть уникальным. Иногда нам нужно, чтобы завершение или продолжение асинхронной операции выполнялись в том же контексте, откуда было запущено. Например, приложения с UI. После нажатия на кнопку мы запускаем асинхронную операцию, результат которой нужно вывести на экран. Но мы не сможем получить доступ к UI элементу, так как он находится в другом потоке. Для этого нам нужно запустить обновление данных в контексте UI потока. Именно для этого и нужен контекст синхронизации.

Контекст синхронизации при работе с Task и Thread

Комбинирование задач

Есть ситуации, когда нам нужно ожидать выполнения нескольких задач, для этого мы можем использовать комбинаторы задач.

Task.WaitAll();
Task.WaitAny();
Task.WhenAll();
Task.WhenAny();

Но нужно быть внимательным, так как WaitAll и WaitAny являются блокирующими операциями. Вместо них желательно использовать WhenAll и WhenAny.

Как получить результат?

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

Блокирующее получение результата:

.Result
.GetAwaiter().GetResult() - //лучше не использовать так как этот метод предназначен для компилятора, а не для нас.
.Wait()

Асинхронное:

await

Что такое sync over async deadlock?

Продолжение задач

Есть ситуации, когда нам нужно выполнить несколько операций одну за одной. Для этого у нас есть метод ContinueWith, с помощью которого можно построить цепочку продолжений.

Пример:

var task = Task.Run(() => Console.WriteLine("Async task"));
var nextTask = task.ContinueWith((prevTask) => {
	Console.WriteLine("Continuation");
});
nextTask.ContinueWith((prevTask) => {
	Console.WriteLine("Last Continuation");
});

Мы можем настраивать условия продолжения используя класс TaskContinuationOptions. С его помощью мы можем строить дерево задач, запускать продолжения по условиям и т. д.

Официальная документация

Обработка исключений

Работа с исключениями в асинхронном коде отличается от синхронного. Мы можем и не узнать об исключении, если не будем явно его обрабатывать. А в более старых версиях .NET это могло привести к падению приложения.

Обработка исключения при использовании await:

try
{
	await Task.Run(() => { throw new Exception(); });
}
catch (Exception e)
{
	// 
}

По умолчанию ContinueWith выполняется независимо от того произошло ли исключение в предыдущей задаче. Но мы можем его настроить двумя способами: в самом продолжении проверить предыдущую задачу или сделать отдельное продолжение, которое будет вызвано только при возникновении исключения.

Task.Run(() => { throw new Exception(); })
	.ContinueWith((prev) => {
		if (prev.IsFaulted)
		{
			//
		}
	});

Task.Run(() => { throw new Exception(); })
	.ContinueWith((prev) => {
		
	}, TaskCreationOptions.OnlyOnfaulted);

Стоит избегать асинхронных методов, которые ничего не возвращают (async void). Так как при возникновении исключения внутри метода, мы просто не сможем его обработать.

Комбинаторы задач также по-разному предоставляют исключения:

  • Task.WaitAll() — вернёт AggregateException;
  • Task.WhenAll() — вернёт только первое исключение;

Отмена задач

Если нам нужно отменить выполнение асинхронной задачи мы можем воспользоваться классом CancellationToken. Про него я рассказывал раньше.

async/await

Основная идея этого подхода заключается в написании асинхронного кода как синхронного. Это позволило создать более дружелюбный интерфейс для работы с асинхронностью.

Что делает async?

  • Создаёт машину состояний, которая обрабатывает все продолжения и синхронизации.
  • Разрешает использовать await.
  • Позволяет передавать вверх по стеку результат и исключения, используя Task.

Что делает await?

  • Позволяет не блокирующее ожидать результат.
  • Запуск продолжения в нужном потоке.
  • Возвращает результат или исключение.

Заблуждения по поводу await

  • Запускает операцию асинхронно.
  • Являться синтаксическим сахаром над Task.ContinueWtih.
  • Обязательно запускает продолжение в новый поток.
  • Всегда работает асинхронно.

Советы

  • Не используйте комбинацию async void — вы не сможете отловить исключение, а также ожидать выполнение метода.
  • Методы помеченные как async должны внутри себя содержать await.
  • Старайтесь вежде использовать не блокирующее ожидание await вместо блокирующего.
  • Для выполнения продолжительных операций используйте Task.Factory.StartNew вместе с TaskCreationOptions.LognRunning.
  • Используйте await t.ConfigureAwait(false) для библиотечного кода.
  • Не используйте совместно await и ContinueWith, так как они ничего не знают друг о друге.

Что осталось за кадром?

  • Асинхронные потоки
  • ValueTask
  • Progress

Ссылки

 Нет комментариев    52   23 дн   .net   c#

Плёнка

Уже год я занимаюсь увлекательным хобби — плёночная фотография. Делюсь полезными ссылками для начинающих, своими обзорами на пленку.

Зачем и как?
Почему я снимаю на пленку

Хочу снимать на пленку. С чего начать?

Вопросы про пленочную фотографию

Где проявить плёнку в Киеве?

Где проявить в других городах и странах?

Магазин с самым большим выбором плёнки.

Фото в рамке
Проявляют и сканируют: C-41, Е-6, D-76. Более детально можно посмотреть на сайте.
В продаже есть большой выбор плёнок 135 и 120 типа, а также для моментальной фотографии (Polaroid и Instax). В магазине всегда можно найти десяток камер.

Фотофонд
Проявляют и сканируют: C-41, Е-6, D-76, ECN-2 (со смывом сажи).
Продают множество фототоваров (пленки, камеры, акксесуары и т. д.).

Photovision
Проявляют и сканируют: C-41, Е-6, D-76, ECN-2 (со смывом сажи).
Продают в основном пленки Kodak.

Пленки

Fujifilm Superia 100 (просрочена 2012 год.)

Polaroid High Definition 200 (просрочка 2002)

Kodak Pro Foto 100 (просрочка 2009)

Kodak Vision3 250D

Kodak Vision3 500T

Kodak ColorPlus 200 pushed to 400 ISO

Kodak Ektar 100

Kodak Ultramax 400

Kodak Gold

Kodak Portra 400

Kodak TMax 400

Kodak Ektachrome E100

Ilford Kentmere 400

Ilford Ortho Plus 80

Ilford HP5 400

Lomography 400

Kosmo Foto

Статьи с тегом «пленка»

Ilford Ortho Plus 80

Новая ортохроматическая плёнка от компании ilford. Раньше эмульсия уже использовалась в листовом формате. Недавно начали производить в 135 и 120 формате. Не чувствительная к красному и оранжевому цвету, имеет мелкое зерно и высокий контраст.

Мне плёнка понравилась своим контрастом и олдскульным видом. Для удобства снимал как 100 ISO.

Вечерний Киев и Kodak Vision3 500T

Протестировал киноплёнку Kodak Vision3 500T. Так как она предназначена для съёмки с искусственным светом — прогулялся с ней вечером после работы. Что сразу бросается в глаза так это насыщенный красный цвет. Днём использовал без фильтра из-за чего картинка немного синеватая, как по мне, в этом есть свой шарм.

В дополнение: Проявка кинопленок. ECN-2 или C-41?

2019

Решил подвести небольшие итоги уходящего года.

Увлечение года — плёночная фотография

Больше года думал о том, чтобы попробовать поснимать на плёнку. Никак руки не доходили до того, чтобы начать. Этот процесс ускорила девушка, подарив на день рождения фотоаппарат. На этот день как раз приходила поездка в Амстердам, взял с собой 4 катушки и начал снимать. После приезда думал, что результат будет не очень, но на самом деле приятно удивился. Сегодня плёнка для меня не только как способ зафиксировать момент, но и медитативный процесс. Потом купил ещё 2 камеры, отснял > 30 катушек, каждый раз пробуя новую.

В следующем году хочу попробовать средний формат. Скоро в лаборатории, в которой проявляю плёнку, появится в аренде средний формат. Смотрю в сторону Hasselblad 500, но цена заставляет отложить покупку на неопределённое время.

Про пленку хорошо рассказал Сергей Король в своих постах.
Почему я снимаю на пленку
Хочу снимать на пленку. С чего начать?
Вопросы про пленочную фотографию

Событие года — смена работы

Ушёл из Террасофта в другую компанию, которой стал Эпам. В Террасофте стало скучновато и не так интересно, хоть компания и процессы нравились. Это скорее импульсивный рывок, хотелось новых задач, вызовов и возможностей развиваться. Эпам закрывает мои потребности на сегодня. Радует что есть много возможностей профессионально развиваться.Конечно, пока прошёл только месяц и рано ещё судить, но тенденция нравится.

Путешествия

Год выдался насыщенным на путешествия. Посетил 4 страны, из которых больше всего запомнились поездки в Рим и Амстердам. Амстердам стал для меня первой поездкой в этом году, а также реализовал давнюю мечту — отпраздновать день рождения здесь. Рим зацепил архитектурой, узкими улочками и приятным морем. Потом была поездка с компанией друзей в Турцию, Мармарис показался скучным по сравнению с прошлогодней поездкой в Кемер. Запомнилась экскурсия по островам на яхте, где посетили не только сами острова, но и плавали в море.

Транспорт Растояние
Поезд 8365 км
Автобус 1548 км
Машина 2430 км
Самолет 6833 км

Небольшая статистика преодаленного расстояния

Покупки года

Canon Canonet QL17

Любимая плёночная камера на сегодня. Купил, чтобы постоянно таскать с собой, так как лёгкая и приятная в управлении. С её помощью начал больше фотографировать. Раньше это было проблематично, так как носить с собой 1,5кг зеркалку неудобно. Осталось только достать для неё вспышку и будет полный комплект.

Мышка Logitech M590
Писал о ней в обзоре. Считаю лучшей мышкой для мака и не только. Может одновременно работать с двумя компьютерами, пришёл на работу — подключил к рабочей машине, дома — к ноутбуку. Поддерживает дополнительные жесты, к которым так привыкаешь на маковском тачпаде.

Новый софт

Things 3
Удобное todo приложение, до него пробовал больше 10 приложений, но ни одно не удовлетворяло полностью. Здесь ситуация другая, приложение имеет красивый, логичный интерфейс. Набор функций сведён к минимуму, есть только то что нужно. Полезная особенность — окно быстрого ввода, записывай мысль из любого места в системе. Минусы, это: цена и поддержка только техники Apple. Радует, что разработчики постоянно выкатывают новые обновления, которые содержат как новые фичи, так и улучшения для уже существующих.

Reeder
Открыл для себя RSS, не понимаю, почему раньше обходил эту технологию. Теперь можно не проверять блоги, за которыми слежу на наличие новых постов, они сами попадают в Reeder. Можно скачать мобильное приложение, с синхронизацией и оффлайном для чтения в метро.

Rider
Кросс-платформенная IDE для C#. Вот и настал тот момент, когда отказался от Visual Studio. Райдер быстрее и функциональнее. Важный фактор — поддержка MacOS, так как версия студии под мак бесполезная и неудобная. Содержит мощный набор инструментов для работы с базами данных, JavaScript-ом и рефакторингом. На новом месте работы вернулся в Visual Studio, так как пока нельзя использовать Rider, но для личных проектов остался незаменим.

Музыка

Любимый русский панк-рок коллектив.

Старый добрый Nickelback постоянно возвращает в мои школьные года.

Ну и куда же без альбома Worlds от Porter Robinson, который я уже слушаю с момента выхода.

Разные достижения

Посидел полтора месяца на диете. Как результат — скинул ~10 кг. Пока рано расслабляться, еще есть над чем работать в следующем году.

Начал вести дневник, записываю туда мысли и рефлексирую.

Начал ставить цели на месяц и неделю. Применил несколько методик: Agile Results, GTD, P.A.R.A.

Написал магистерскую работу, в следующем месяце защита и выпуск.

Планы на 2020

  • Пройти assessment на сеньор разработчика.
  • Сдеть экзамен на сертификат GCP: associate cloud engineer.
  • Подтянуть английский язык.
  • Посетить 3 новые страны.
  • Сдать экзамен разработчика C# от Майкрософт.
  • Найти идею для проекта, который будет переть.
  • Разобраться с версткой, научиться делать адаптивные сайты.
  • Снять фильм года. Что это такое?
 Нет комментариев    132   2 мес  

Ссылки — 19

Рандомное фото на пленку.

Идеи для программистов

Много начинающих программистов — сам был таким — маются от вопроса: чего бы такого классного напрограммировать. Месяц за месяцем, год за годом проходят в ожидании достойной идеи™. «Вот бы мне проект, я уж я бы взялся за него, я б тогда выложился на все сто».

Некоторым везёт, и они быстро попадают в классную команду на крутой проект. Кому повезло меньше, сидит в суровом энтерпрайзе и жаждет поделать какой-нибудь пет-проджект для души. Вот только идеи нет…

Я придумал решение. Надо брать любую штуку, которая вам нравится, и просто попытаться повторить её. Нравится тетрис? Запрограммируйте тетрис. Нравится тот же Майнкрафт? Запилите свой Майнкрафт. Если при этом не хочется возиться с трёхмеркой (хотя, чего там возиться, с первого-то взгляда? :—) — делайте двумерный.

Я однажды так делал игрушку с паравозиками. Правда, интерфейс мне было неинтересно делать. Зато крайне увлекала логика переключения стрелок, семафоров, решение коллизий и всё такое. Вот так я и играл в эти свои паровозики: в юниттестах.

Смысл не в том, чтобы сделать продукт. И даже не в том, чтобы выключить радары, в поисках крутую идею. Смысл в том, чтобы, пока крутая идея не пришла, занять время чем-то полезным. А потом, когда придёт время клёвого проекта, скилл уже будет прокачан и будет шанс не запороть идею, а таки реализовать её.

Ещё один бонус: в повторении чужих проектов можно выбирать, на чём концентрироваться. В готовых-то продуктах уже всё продумано: можно брать готовые интерфейсы, логику, арты и прочее-прочее. Плюс выбираем для воспроизведения то, что нравится. А не суровый энтерпрайз (хотя, кому-то и это нравится). И ещё не надо заморачиваться с прочими нюансами работы над реальными проектами: аналитика, требование, планирование, коммуникации и прочее-прочее. Делаем чисто для себя, как упражнение из учебника.

На самом деле это решение придумал не я, конечно же. У древних мастеров это был главный способ прокачиваться: повторять за лучшими. Ну и чем мы хуже?

Оригинал статьи: https://t.me/anatoly_burov_channel/116 

Ранее Ctrl + ↓