Task.Factory.FromAsync

Task.Factory.FromAsync

CSharpCooking

В устаревшей модели асинхронного программирования (Asynchronous Programming Model – АРМ) использовались пара методов, имена которых начинаются с Begin и End, а также интерфейс по имени IAsyncResult.

В целях иллюстрации возьмем класс Stream из пространства имен System.IO и рассмотрим его метод Read. Вызов метода Begin* инициирует операцию, возвращая объект IAsyncResult, который действует в качестве признака для асинхронной операции. Когда операция завершается (или отказывает), запускается делегат AsyncCallback. Целевой метод данного делегата затем вызывает метод End*, который предоставляет возвращаемое значение операции, а также повторно генерирует исключение, если операция потерпела неудачу.

Шаблон АРМ неудобен в применении и проще всего иметь дело с методами АРМ, вызывая метод адаптера Task.Factory.FromAsync, который преобразует пару методов АРМ в объект Task. Внутренне он использует TaskCompletionSource, чтобы предоставить объект задачи, которой отправляется сигнал, когда операция АРМ завершается или отказывает.

Метод FromAsync требует передачи следующих параметров:
– делегат, указывающий метод BeginXXX;
– делегат, указывающий метод EndXXX;
– дополнительные аргументы, которые будут передаваться данным методам.

Метод FromAsync перегружен для приема типов делегатов и аргументов, которые соответствуют практически всем сигнатурам асинхронных методов, определенным в .NET.

В приближенной реализации метода Task.Factory.FromAsync создается объект TaskCompletionSource, к которому привязывается результат операции. В callback просто вызывается End-метод и результат задается в источник задачи. Таким образом, сложная асинхронная последовательность Begin/End инкапсулируется в Task, что упрощает дальнейшее использование. Это позволяет работать с асинхронными методами через современный API на основе задач, не вдаваясь в детали реализации АРМ.

#параллелизмзадач #программирование #сишарп #taskfactory #taskparallelism #csharp #csharpdotnet #csharpprogramming

Report Page