Подтвердить что ты не робот

Где/как я могу узнать, использует ли класс .net IOCP?

Обновление

Я задал неправильный вопрос, перефразировал (основываясь на большой информации об ответах и ​​комментариях):

Есть ли хороший источник для асинхронных операций .net async, являющихся реальным async, таким образом, IOCP или async (overlapped)? Есть ли какой-нибудь быстрый способ узнать, делают ли это несколько классов?

Пример неверия разработчиков инфраструктуры вслепую

Естественной отправной точкой для создания FileStream является статический метод File.Open(), документация для которого ничего не говорит о синхронности созданного FileStream! Это также не позволяет вам предоставлять FileOptions (которые используются для указания волшебного флажка FileOptions.Asynchronous).

Вместо этого FileStream создается с помощью FileOptions.None. Любые асинхронные операции легко подделываются обязательной реализацией базового класса Stream, который просто переносит соответствующий синхронный метод в делегат и вызывает его в пуле потоков с использованием метода BeginInvoke().

Это отклонение от обычной философии дизайна "ямы успеха", где все в .NET, похоже, работает так, как вы думаете, без необходимости внимательно читать документацию и/или постепенно обнаруживать неясные уловы и gotchas с течением времени.


Я пытался найти информацию об использовании IO Completion Ports в .NET.

Есть ли какой-либо хороший способ узнать, использует ли данный .NET-класс порты ввода-вывода IO? (без необходимости запускать некоторые тесты каждый раз, когда вы используете новый класс.

Я пробовал документы msdn для некоторых классов и методов, и я ничего не смог найти на нем.

Еще лучше, было бы, если бы там был список со списком классов с использованием IOCP.

4b9b3361

Ответ 1

Как правило, BCL предлагает только асинхронные API, если они реализованы с использованием async IO, поддерживаемых ядром Windows. Выявление методов async, которые не используют async kernel-IO, было бы известным анти-шаблоном async-over-sync, о котором наверняка знают дизайнеры BCL. Это было бы не только бесполезно, но и вредно для производительности и вводить в заблуждение. Они этого не делают.

Windows может выполнять асинхронное ввод-вывод с использованием IOCP или с использованием обычного перекрывающегося ввода-вывода. Оба они эффективны, асинхронны и поэтому более масштабируемы, чем блокировка IO.

Все это прозрачно для вас. Положитесь на async, чтобы быть действительно асинхронным, и синхронизация действительно синхронизирована.

Если есть сомнения, загляните под капот с помощью Reflector. Всякий раз, когда я это делал, я нашел подтверждение того, что я только что сказал. Мне еще предстоит увидеть отклоняющийся случай.

Что вы видите с Reflector, так это то, что BCL вызывает асинхронные версии соответствующих API Win32. В качестве примера я рассмотрю файлы и сокеты:

  • FileStream.BeginRead косвенно вызывает Win32Native.ReadFileNative с указателем на структуру NativeOverlapped. Указатель получается путем вызова Overlapped.Pack. Обратный вызов завершения сохраняется таким образом. Невозможно определить способ вызова обратного вызова с помощью Reflector, поскольку эта часть существует в нативной части CLR. Я не могу сказать, используется ли IOCP, но я могу сказать, что используется async IO.
  • Socket.BeginRead косвенно вызывает WSARecv. Код довольно сложный. BCL, похоже, может использовать перекрывающиеся IO, а также IOCP в зависимости от ОС. Проверка производится в Socket.InitializeSockets. Решение о том, какое IO использовать, хранится в Socket.UseOverlappedIO. Если эта переменная ложна, в конечном итоге вызывается Socket.BindToCompletionPort.

Итак, для Sockets это явно IOCP на современных ОС. Для файлов я не могу сказать.

Мне лично не особо интересно, какой тип асинхронного ввода-вывода используется до тех пор, пока он не блокируется. Это так.

Ответ 2

Порт завершения ввода-вывода - это сильная деталь реализации платформы, которую .NET не может слепо зависеть от доступности. И это не так, он оставляет его для хоста CLR, чтобы реализовать клей для поддержки операционной системы для него. Основной интерфейс хостинга - IHostIoCompletionManager, доступный с .NET 2.0

Итак, если вы хотите получить твердую гарантию, что они действительно используются, вам нужно получить источник хоста CLR, который вы используете. Это трудно найти, их много, и вам нужно будет обратиться в Microsoft, чтобы получить доступ к источнику. В источнике доступен только хост SSCLI20, он устарел и охватывает только хост по умолчанию. Это было само по себе, чтобы позволить PAL предоставлять порт завершения ввода-вывода, безусловно, фактически не присутствовать в реальных хостах CLR, которые вы когда-либо выполняли.

Вы не были конкретно о том, какие платформы вы считаете. Некоторые факторы:

  • ASP.NET: да, порты завершения ввода/вывода - большая часть для сокетов
  • SQL Server: довольно вероятно, но не slamdunk, он имеет умение делать что-то по-другому.
  • Рабочий стол: да, для любой версии .NET >= 2.0, которая работает на ветке NT
  • Compact: определенно не
  • Микро: определенно не
  • XBox: маловероятно, детали ОС - большая тайна.
  • Silverlight: версия Windows CoreCLR.dll использует его, но без ThreadPool.BindHandle
  • Phone7: аналогично Silverlight
  • Телефон8: большая тайна, возможно.

Подчеркивая, что это просто образованные догадки, которые не подкреплены доказательством. Вопрос в другом случае довольно странный, это не похоже на то, что у вас будет альтернатива, если вы узнаете, что асинхронный ввод-вывод был выполнен с перекрытием ввода-вывода.

Ответ 3

По моему опыту, следующие API на основе IOCP:
FileStream: BeginWrite/BeginRead. ПРИМЕЧАНИЕ. При создании FileStream вы должны передать FileOptions.Asynchronous DNS: BeginGetHostByName/BeginResolve
Гнездо: BeginAccept/BeginConnect/BeginReceive и т.д.
WebRequest: BeginGetRequestStream/BeginGetResponse
SqlCommand: BeginExecuteReader/BeginExecuteNonQuery и т.д. Вы должны установить AsynchronousProcessing как true (по умолчанию это значение false).
WebServcie: BeginXXX в WebServiceProxy, сгенерированный WCF и InvokeAsync в ClientBase