Ответ 1
Операции WCF могут быть определены с использованием либо синхронного, EAP, либо (как .NET 8.5) TAP. Из MSDN:
Клиенты могут предложить разработчику любую модель программирования, которую они выбирают, при условии, что будет наблюдаться базовая модель обмена сообщениями. Таким образом, службы могут выполнять операции каким-либо образом, при условии соблюдения указанного шаблона сообщения.
Фактически вы можете иметь все 3 шаблона в одном интерфейсе контракта, и все они будут относиться к одному и тому же сообщению.
На проводе нет никакой разницы в том, как вы выполняете операции. WSDL (который WCF создает из каждой конечной точки ABC-адрес, привязка и контракт) не содержит этой информации. Он создается из описаний операций.
Если вы посмотрите на класс OperationDescription
, который используется в ContractDescription
, вы увидите, что каждая операция имеет следующие свойства: SyncMethod
, BeginMethod
, EndMethod
и TaskMethod
. При создании описания WCF объединяет все методы в соответствии с именем операции в одну операцию. Если существует некоторая несогласованность между операциями с одним и тем же именем в разных шаблонах (например, разными параметрами), WCF генерирует исключение, в котором точно указано, что именно. WCF автоматически предполагает (необязательно) суффикс "Async" для методов на основе задач и префикс Begin/End для APM.
В этом смысле клиентская и серверная стороны совершенно не связаны. Утилита, которая генерирует прокси-классы из WSDL (svcutil
), может создавать прокси для любого шаблона выполнения. Это даже не должно быть WCF-сервисом.
На стороне сервера, если реализовано несколько шаблонов, WCF будет использовать только один из следующих порядков приоритета: Task, Sync и APM. Это документировано где-то в MSDN, я просто не могу найти его прямо сейчас. Но вы можете посмотреть исходный источник здесь.
В заключение вы можете безопасно изменить свою реализацию сервера, если вы не изменяете сообщение, которое представляет операция.
Что касается масштабирования (должен быть другой вопрос IMO)
- Стандартные значения WCF для дросселирования обновлены в .NET 4.5 до гораздо более разумных значений и теперь зависят от процессора (см. здесь).
- Никаких изменений в отношении проблемы с пулом потоков. Проблема связана с первоначальным размером пула потоков портов завершения, который изначально устанавливается в 4 раза больше количества логических процессоров. Вы можете использовать
ThreadPool.SetMinThreads
, чтобы увеличить количество на некоторый коэффициент (см. этот пост). Этот параметр также может быть полезен на стороне клиента.
Если вы используете async на стороне сервера (при вызове других сервисов, базы данных и т.д.), ситуация с потоками может значительно улучшиться, потому что вы не будете тратить нитки потоков нитей, которые только ждут завершения ввода-вывода.
Лучше всего в этих ситуациях сделать много тестов.