Страницы с тегами : TPL
Блеск и нищета Task Parallel Library
Task Parallel Library (пространство имен System.Threading.Tasks) появилась еще в .NET 4, но большой популярностью не пользовалась. На подходе компилятор C# 5, который поддерживает конструкцию async\await. В скомпилированом коде async метод превращается в метод возвращающий Task\Task<T>. Поэтому в скором времени использование TPL станет повсеместным.
Task Parallel Library – имеет очень мощные механизмы: вложенные (nested) задачи, локальные очереди для потоков, чтобы уменьшить латентность, work-stealing алгоритмы для работы, кучи опций запуска задач и продолжений, различные планировщики. Все создано в лучших традициях оптимизации асинхронного кода.
Но, TPL создавался до мозга костей практиками и цели сделать библиотеку удобной для потребителей даже не ставилось судя по всему.
- Как это не смешно, то в стандартной библиотеке нету метода, позволяющего обернуть значение T в Task<T>. (Только в .NET 4.5 появился Task.FromResult)
- Сам объект Task представляет из себя “задачу”, которая может быть как еще не запущена, так и уже выполняться. Поэтому работа с разными Task_ами будет осуществляться по-разному.
- Task не является immutable объектом, метод ContinueWith изменяет саму задачу.
- Функция ContinueWith срабатывает при любом завершении задачи, в том числе отмене или ошибке. Необходимо каждый раз указывать флаги.
- Исключения внутри задач собираются в один объект, что затрудняет структурированную их обработку.
- Метод ContinueWith принимает Func<Task, T>, а не Func<Task, Task>. Это значит что единственный способ связать две задачи – создать вложенную (nested), что может привести к переполнению стека при завершении цепочки вложенных задач.
Последний пункт особенно актуален. Даже был сделан extension-метод Unwrap, который позволяет писать код в виде:
var task = SomeFuncReturningTask(...) .ContinueWith(t => SomeOtherFuncReturningTask(t.Result)) .Unwrap().ContinueWith(...) .Unwrap().ContinueWith(...);