При параллелизме задач следует особенно внимательно следить за переменными, сохраненными в замыканиях (closures). Помните, что в замыканиях сохраняются ссылки (а не значения), и это может привести к неочевидным ситуациям с совместным использованием данных.
Microsoft предоставляет великолепную документацию по этой теме. Рекомендую прочитать по крайней мере обзор «Asynchronous Programming» и «Task-based Asynchronous Pattern (TAP)». Кроме этого, также имеется документация «Async in Depth».
В современных асинхронных приложениях .NET используются два ключевых слова: async и await. Ключевое слово async добавляется в объявление метода и имеет двойное назначение: оно разрешает использование ключевого слова await внутри этого метода и приказывает компилятору сгенерировать для этого метода конечный автомат по аналогии с тем, как работает yield return. Метод с ключевым словом async может вернуть Task, если он возвращает значение; Task — если он не возвращает значения; или любой другой «сходный» тип — такой, как ValueTask.
Если рассматривать приложение как огромный конечный автомат, поведение приложения может быть описано как реакция на серию событий с обновлением своего состояния на каждое событие.
Другая форма конкурентности — реактивное программирование
Асинхронное программирование — мощная разновидность конкурентности
асинхронной операции — некоторой запущенной операции, которая завершится через некоторое время.
Обещание (future/promise), или преднамеченный тип — тип, представляющий некоторую операцию, которая завершится в будущем. Примеры современных типов обещаний в .NET — Task и Task.
Асинхронное программирование
Разновидность конкурентности, использующая обещан