Должны ли мы переключиться на использование асинхронного ввода-вывода по умолчанию?
С преимуществами async I / O, и теперь его довольно легко кодировать и компоновать (используя методы Await и TAP). Мне интересно, если мы будем использовать async по умолчанию и только настроим производительность, используя синхронизацию, когда это необходимо.
Async I / O освобождает вызывающий stream и позволяет делать что-то еще в ожидании результата. С другой стороны, asynchronous ввод-вывод немного медленнее синхронизации.
Чтобы обеспечить соответствие пользовательских интерфейсов, дизайнеры WinRT сочли приемлемыми предлагать только асинхронные методы.
- Запуск двух асинхронных задач параллельно и сбор результатов в .NET 4.5
- Разница между TPL и async / await (Обработка streamов)
- В чем разница между возвратом пустоты и возвратом задачи?
- ConfigureAwait подталкивает продолжение в stream пула
- Шаблон для самоотдачи и перезапуска задачи
AFAIK Файл ввода / вывода Windows внутри – asynchronous. Глядя на это наивно, мне непонятно, почему asynchronous файл i / O в .NET должен быть медленнее, чем синхронизация вообще.
Я, как правило, предпочитаю простоту и надежность и только при необходимости настраиваюсь на производительность. Раньше мы использовали синхронизацию по умолчанию, за исключением вызова некоторых сервисов и там, где платформы, такие как телефон, применяли asynchronous режим. Мы редко настраиваемся с помощью async.
- Лучший способ конвертировать метод async на основе обратного вызова в ожидаемую задачу
- Очередь процесса с многопоточным или задачами
- Каков правильный способ отмены асинхронной операции, которая не принимает CancellationToken?
- Секвенирование и реорганизация задач
- Выполнение задач параллельно
- Выполнение задачи в фоновом режиме в приложении WPF
- Почему это асинхронное действие зависает?
- Запуск задач в foreach Loop использует значение последнего элемента
Использование async IO стало очень простым с C # 5, но с ним все еще связаны затраты на производительность. Например, вам нужно посыпать новые ключевые слова, где ранее нигде не было необходимости. Вы должны изменить тип возвращаемого метода.
Если позже вы решите, что метод должен выполнить IO, вам нужно изменить всю цепочку вызовов, чтобы переключиться на asynchronous. Это нелокальное изменение, распространяющееся на другие модули.
Вы не можете профилировать asynchronous ввод-вывод. Инструменты профилирования ничего не получают. Если вы приостанавливаете отладчик, ничего не происходит ни на одном из стеков streamов. Кажется, никто ничего не делает. Это связано с тем, что async IO не поддерживает stream. Это всего лишь структура данных (объект в ядре).
Решение также зависит от типа приложения. В приложении WinForms или WPF я предпочитаю использовать async, потому что он так хорошо интегрируется в stream пользовательского интерфейса.
В настройке ASP.NET / WCF основное преимущество заключается в том, что вы не исчерпываете пул streamов, когда вы вызываете длительные бэкэнд-сервисы. Если у вас нет такой проблемы, и я думаю, что это довольно редко, вы получаете очень мало от async IO. Фактически вы теряете производительность по умолчанию.
В настройке метро решение было принято для вас. Microsoft (законно) решила торговать продуктивностью разработчиков для пользователей.
Так что это не четкое решение. На данный момент плюсы и минусы являются довольно слабыми. По этой причине я воздержусь от однозначной рекомендации. Это зависит от конкретного случая.
Я бы рекомендовал использовать async
когда у вас есть естественно-асинхронная операция, а также синхронный код. Это правда, что async
немного медленнее, но в большинстве случаев это похоже на «включение радио в вашем Hummer» медленнее.
В программах пользовательского интерфейса async
повышает отзывчивость. В серверных приложениях async
увеличивает масштабируемость.
AFAIK Файл ввода / вывода Windows внутри – asynchronous. Глядя на это наивно, мне непонятно, почему asynchronous файл i / O в .NET должен быть медленнее, чем синхронизация вообще.
Асинхронный код медленнее, поскольку он должен выделять структуры для отслеживания асинхронной операции; синхронный код просто использует текущий stream (и его стек). Таким образом, сама операция не медленнее, но в целом есть небольшое снижение скорости из-за большего давления на сборщик мусора.
Я, как правило, предпочитаю простоту и надежность и только при необходимости настраиваюсь на производительность.
Согласен. Если у вас есть операция, которая является естественно асинхронной (например, I / O), выставляйте async
API. И если у вас есть операция, которая, естественно, синхронна, выставляйте синхронный API. У Стивена Туба есть пара замечательных сообщений в блоге об этом ( здесь и здесь ).