TAP Flashcards
Неявное создание и запуск задач
Parallel.Invoke(() => DoSomeWork(), () => DoSomeOtherWork());
Равно ли количество созданных экземпляров методом Invoke количеству переданных делегатов
Число экземпляров Task, созданных Invoke в фоновом режиме, не обязательно равно числу предоставленных делегатов. Библиотека параллельных задач может применять различные оптимизации, особенно с большим количеством делегатов.
В каком случае предпочтительно использовать методы Run()
Методы Run — предпочтительный способ создания и запуска задач, если не требуется более жесткий контроль над созданием и планированием задачи.
В каком случае предпочтительно использовать Task.Factory.StartNew()
Используйте этот метод, если нет необходимости разделять создание и планирование и требуются дополнительные параметры создания задач или использование определенного планировщика, а также при необходимости передачи дополнительного состояния задаче через ее свойство AsyncState
К каким переменными имеется доступ при использовании лямбда выражений для создания делегата
При использовании лямбда-выражения для создания делегата имеется доступ ко всем переменным, видимым на этом этапе в исходном коде
Какие проблемы могут возникнут с захватом переменных в циклах
В некоторых случаях, особенно в циклах, лямбда-выражение не перехватывает переменную, как можно было бы ожидать. Оно только перехватывает окончательное значение, а не значение, изменяющееся после каждой итерации.
Как решить проблему с захватом переменных в циклах
Доступ к значению для каждой итерации можно получить, предоставив объект состояния задаче через ее конструктор.
Каким образом из объекта задачи можно получить доступ к объекту состояния
Состояние передается в качестве аргумента делегату задачи, и доступ к нему можно получить из объекта задачи с помощью свойства Task.AsyncState.
Каким образом можно указать планировщику задач способ планирования задачи в пуле потоков
API, в которых создаются задачи, предоставляют перегрузки, принимающие параметр TaskCreationOptions. Указывая один из этих параметров, пользователь задает планировщику задач способ планирования задачи в пуле потоков.
Как указать задачу, которую нужно выполнять по завершению предыдущей
С помощью методов Task.ContinueWith и Task.ContinueWith можно указать задачу, которую нужно запускать по завершении предшествующей задачи.
Как избежать создания нескольких экземпляров задач - продолжения для каждой предшествующей задачи
Поскольку метод Task.ContinueWith является экземплярным, вызовы этого метода можно объединять в цепочку, а не создавать экземпляр объекта Task для каждой предшествующей задачи.
Создание отсоединенных дочерних задач и их особенность
Если в пользовательском коде, выполняемом в некоторой задаче, создается новая задача и не задается параметр AttachedToParent, новая задача не синхронизируется с родительской никаким особым способом.
Создание присоединенной дочерней задачи
Если пользовательский код, который выполняется в задаче, создает новую задачу с параметром AttachedToParent, эта новая задача считается присоединенной дочерней задачей родительской задачи.
Каковы основные причины ожидания задач
Как правило, ожидание задачи выполняется по одной из следующих причин.
* Основной поток зависит от конечного результата, вычисленного задачей. * Необходимо обрабатывать исключения, которые могут быть созданы из задачи. * Приложение может завершиться до окончания выполнения всех задач. Например, выполнение консольных приложений завершается после выполнения всего синхронного кода в Main (точке входа приложения).
Какие экземплярные и статические методы позволяют ожидать завершения задач
WhenAll, WhenAny, Delay и FromResult
Как отменить ожидание/выполнение
Можно создать токен и выдать запрос отмены позднее с помощью класса CancellationTokenSource.
В каких случаях полезен метод WhenAny
Метод WhenAny особенно полезен в следующих ситуациях.
* Избыточные операции. Рассмотрим алгоритм или операцию, которые можно выполнить несколькими способами. Метод WhenAny можно использовать для выбора операции, завершающейся первой, и последующей отмены оставшихся операций. * Операции с чередованием. Можно запустить несколько операций, которые все должны завершиться, и использовать метод WhenAny для обработки результатов при завершении каждой операции. После завершения одной операции можно запустить одну или несколько дополнительных задач. * Регулируемые операции. Метод WhenAny можно использовать для расширения предыдущего сценария путем ограничения количества одновременно выполняемых операций. * Операции с истекшим сроком действия. Метод WhenAny можно использовать, чтобы сделать выбор между одной или несколькими задачами и задачей, завершающейся после определенного времени, например задачей, возвращаемой методом Delay.
Какие основные методы представляет TaskFactory для создания, запуска задач и задач продолжения
StartNew, ContinueWhenAny, ContinueWhenAll, FromAsync
Какие состояния возможны у задач
Canceled 6 Created 0 Faulted 7 RanToCompletion 5 Running 3 WaitingForActivation 1 WaitingForChildrenToComplete 4 WaitingToRun 2
Задача продолжения
это асинхронная задача, вызываемая другой задачей, которая называется предшествующей, при завершении этой предшествующей задачи
Что можно выполнить с помощью продолжений
- Передавать данные из предшествующей задачи в продолжение.
- Указывать точные условия, при которых продолжение будет вызываться или не будет вызываться.
- Отменять продолжение перед его запуском либо совместно с его выполнением.
- Определять подсказки, как должно планироваться продолжение.
- Вызывать несколько продолжений из одной и той же предшествующей задачи.
- Вызывать одно продолжение по завершении всех или одной из нескольких предшествующих задач.
- Прикреплять продолжения одно после другого до любой произвольной длины.
- Использовать продолжение для обработки исключений, вызванных предшествующей задачей.
В каком состоянии создается задача-продолжение
Продолжение — это задача, созданная в состоянии WaitingForActivation
Что будет если вызвать Task.Start в продолжении в пользовательском коде
вызывает исключение System.InvalidOperationException
Создание продолжения для одной предшествующей задачи
Task taskA = Task.Run( () => …)
Task continuation = taskA.ContinueWith(antecedent =>…)