Адаптация асинхронного .NET 4.5 к F # - PullRequest
8 голосов
/ 14 февраля 2012

Библиотеки фреймворка .NET 4.5 довольно широко интегрируют асинхронность на основе задач в стиле C #. Во многих случаях они также продолжают предоставлять пары методов начала / конца в стиле APM. F # может легко адаптировать любой метод к асинхронным вычислениям в стиле F #.

У меня такой вопрос, учитывая, что операция, связанная с вводом-выводом, которая реализована в каркасе как асинхронное начало / конец и основанная на задачах, есть ли преимущество в производительности или памяти при выборе одного из других при адаптации к асинхронному F #?

Например, в .NET 4.5 System.IO.Stream имеет BeginRead и ReadAsync . Это значит, что я могу сделать это ...

type System.IO.Stream with
    member x.AsyncRead(buffer, offset, count) =
        Async.FromBeginEnd(buffer, offset, count, x.BeginRead, x.EndRead)

Или я могу сделать это ...

type System.IO.Stream with
    member x.AsyncRead(buffer, offset, count) =
        x.ReadAsync(buffer, offset, count) |> Async.AwaitTask

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

1 Ответ

2 голосов
/ 14 февраля 2012

Метод расширения AsyncRead ( реализован в терминах FromBeginEnd) уже определен в FSharp.Core. AwaitTask - это просто тонкая оболочка над Task.ContinueWith. Таким образом, все сводится к сравнению Task и async - что более эффективно, или правильное для данной работы. Поскольку вы работаете с async s, единственным значимым отличием будет производительность. Я не эксперт в этом, но я думаю, что async и Task решают одну и ту же проблему, с Task, имеющим преимущество для операций, связанных с процессором.

EDIT

Я недостаточно внимательно прочитал ваш вопрос. Я не знаю окончательного ответа, но, учитывая, что Task и async примерно эквивалентны, я не вижу никакой причины заключать Task в async, если только это не ваш единственный вариант. Методы Begin/End представляют собой более низкую, более легкую абстракцию и, следовательно, кажутся лучшими строительными блоками для async с.

Вспомогательная мысль: тот факт, что AsyncRead не был изменен для использования Task , может быть поучительным.

...