Определение, когда следует реализовать асинхронную модель, основанную на событиях

Асинхронная модель на основе событий применяется для предоставления асинхронного поведения класса. С момента ее появления .NET определяет две модели для предоставления асинхронного поведения: на основе интерфейса System.IAsyncResult и на основе событий. В этой статье описываются ситуации, в которых следует применять ту или иную модель.

Дополнительные сведения об асинхронном программировании для интерфейса IAsyncResult вы найдете в статье об асинхронной модели программирования (APM).

Общие принципы

Обычно для всех асинхронных функций лучше применять асинхронную модель на основе событий. Но есть несколько требований, которым она не полностью соответствует. Если они применимы в вашей ситуации, в дополнение к модели на основе событий следует реализовать модель IAsyncResult.

Примечание.

Модель IAsyncResult очень редко реализуется отдельно, без модели на основе событий.

Рекомендации

Ниже перечислены рекомендации по выбору асинхронной модели на основе событий.

  • Используйте модель на основе событий в качестве основного API для асинхронных возможностей класса.

  • Не предоставляйте модель IAsyncResult, если класс используется в основном в клиентском приложении, например Windows Forms.

  • Предоставляйте модель IAsyncResult только в тех случаях, когда это необходимо для конкретных требований. Например, модель IAsyncResult может потребоваться для совместимости с уже существующими API.

  • Не предоставляйте модель IAsyncResult отдельно, без модели на основе событий.

  • Если потребуется модель IAsyncResult, предоставляйте ее только в качестве дополнительной возможности. Например, если вы создаете прокси-объект, создайте модель на основе событий в качестве стандартного варианта, а модель IAsyncResult предоставляйте опционально.

  • Модели на основе событий следует основывать на вашей реализации модели IAsyncResult.

  • По возможности не размещайте модель на основе событий и модель IAsyncResult в одном классе. Модель на основе событий должна размещаться в классах "более высокого уровня" относительно модели IAsyncResult. Сравните, например, модель на основе событий для компонента WebClient с моделью IAsyncResult в классе HttpRequest.

    • Используйте один и тот же класс для предоставления модели на основе событий и модели IAsyncResult только в том случае, если это необходимо для совместимости. Например, если вы уже опубликовали API, в котором реализована модель IAsyncResult, ее придется сохранить для обеспечения обратной совместимостиIAsyncResult.

    • Также допустимо размещать модель на основе событий и модель IAsyncResult в одном классе в тех случаях, когда сложность объектной модели перевешивает преимущества от раздельной реализации. Гораздо лучше предоставить обе модели в одном классе, чем вовсе не предоставлять модель на основе событий.

    • Если вам придется разместить модель на основе событий в том же классе, что и модель IAsyncResult, используйте EditorBrowsableAttribute со значением Advanced, чтобы обозначить реализацию модели IAsyncResult как дополнительную функцию. В этом случае среды разработки, например Visual Studio IntelliSense, не будут отображать свойства и методы IAsyncResult. Эти свойства и методы будут функционировать как прежде, но не будут захламлять рабочее пространство API-интерфейса для разработчика, работающего в IntelliSense.

Критерии для предоставления модели IAsyncResult в дополнение к модели на основе событий

В описанных выше сценариях асинхронная модель на основе событий дает целый ряд преимуществ, но имеет и некоторые недостатки. Их важно учитывать, если у вас высокие требования к производительности.

Есть три сценария, для которых модель на основе событий подходит хуже, чем модель IAsyncResult:

  • ожидание с блокировкой для одного IAsyncResult;

  • ожидание с блокировкой для нескольких объектов IAsyncResult;

  • опрос завершения для IAsyncResult.

Все эти сценарии можно реализовать с помощью модели на основе событий, но такое решение будет более громоздким, чем использование модели IAsyncResult.

Разработчики часто используют модель IAsyncResult для служб с высокими требованиями к производительности. Например, сценарий с опросом завершения является одним из методов повышения производительности сервера.

Эффективность модели на основе событий ниже, чем у модели IAsyncResult, поскольку она создает несколько объектов (особенно EventArgs) и синхронизируется между потоками.

Следующий список содержит рекомендации на случай, если вы решили использовать модель IAsyncResult.

  • Предоставляйте модель IAsyncResult только в том случае, когда строго необходима поддержка объектов WaitHandle или IAsyncResult.

  • Предоставляйте модель IAsyncResult только в том случае, если у вас уже есть API, который использует модель IAsyncResult.

  • Если у вас есть существующий API, основанный на модели IAsyncResult, постарайтесь в следующем выпуске реализовать и модель на основе событий.

  • Предоставляйте модель IAsyncResult только в том случае, если у вас высокие требования к производительности, которые гарантированно недостижимы при применении модели на основе событий, но могут быть достижимы с помощью модели IAsyncResult.

См. также