2014-01-29 3 views
19

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

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

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

Example of not trusting framework developers blindly

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

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

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


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

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

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

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

+4

Вы планируете избегать таких классов/методов? Или обнять их? Какую ценность вы получаете, зная, если они выполняют свои договорные обязательства? –

+1

Embrace. Причина, по которой я смотрю на это, связана с существующим дизайном, который имеет свои собственные потоки и * не * использование.net async. Разумеется, существуют различные аргументы, которые распространяются вокруг, но главная из них заключается в том, что при вызове в async .net это похоже на то, что касается потока. Пополнение портов ввода-вывода изменяется. Конечно, реальный ответ на это предполагает более подробные измерения и в зависимости от этого, устанавливая «Доказательство концепции» и сравнивая. Производительность кода постоянно улучшается, но это область, которая не изучалась. – eglasius

+3

Я не знаю ни одного обстоятельства (так же как ответ @ usr), где асинхронные API ввода-вывода не делают этого. И я бы ожидал, если вы найдете API ввода-вывода в платформе .NET, который * не * использует их, это для разумной причины (хотя я признаю, что это нигде не документировано). Что вам нужно сделать, так это «подняться на уровень» - доверять разработчикам фреймворка «делать правильные вещи» и полагаться на абстракции, которые выставлены на этом уровне, - и перестать беспокоиться о том, как они достигли их , пользовательские примитивы нижнего уровня. –

ответ

18

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

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

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

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

Что вы видите с рефлектором, так это то, что 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.

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

Мне лично не очень интересно, какой асинхронный IO используется до тех пор, пока он не блокируется. В этом случае.

+1

"Вообще"? У вас есть ссылка на это? Я предполагаю, что «асинхронные API» вы имеете в виду «асинхронные IO API»? –

+1

Строго говоря, не все async IO в WinNT - это IOCP. Вы можете иметь операции async (overlapped), не привязывая их к порту завершения. Но +1, потому что суть того, что вы говорите, истинна. –

+0

@PeterRitchie - это ссылка, мои исследования и мои рассуждения. Ничего официального AFAIK. – usr

18

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

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

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

  • ASP.NET: да, порты ввода/вывода завершающие большое дело для сокетов
  • SQL Server: очень вероятно, но не Slamdunk, он не имеет сноровки делать вещи по-разному
  • Рабочий стол: да, для любого .NET версии> = 2.0, которая работает на ветке NT
  • Compact: определенно не
  • Micro: определенно не
  • XBox: маловероятно, детали OS являются большая тайна
  • Silverlight: CoreCLR.dll для Windows используется, но нет ThreadPool.BindHandle
  • Phone7: похожее на Silverlight
  • Phone8: большая тайна, возможно.

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

+0

+1 Это отличный вклад, я не думал, что в этой области может быть разница в платформе. Целевыми платформами являются в основном asp.net и рабочий стол (ветвь nt). Мой вопрос действительно странный, потому что я начал думать, что использование IOCP было единственным доказательством реального асинхронного ввода-вывода, и это не единственный вариант. Я ищу источники, которые демонстрируют .net использует реальную асинхронную синхронизацию IO для сверстников, которые в какой-то момент думают о деталях реализации .net заканчивается тем, что вместо этого использует поток. – eglasius

+0

+1 для четкой демонстрации знаний низкого уровня. – drankin2112

+0

@ HansPassant, что случилось с щедростью? Разве это не должно быть 500? ;-) – usr

Смежные вопросы