2013-08-15 1 views
3

Проблема может быть описана следующей цитатой из MSDN:Task.Factory.FromAsync и RegisterWaitForSingleObject - не последнее ли убивает полезность первого?

Свойства CommandTimeout будет игнорироваться во время асинхронного метода называет таким, как BeginExecuteReader.

погуглить вокруг для решения этой проблемы я наткнулся на ряд должностей, предлагая с помощью Task.Factory.FromAsync в сочетании с ThreadPool.RegisterWaitForSingleObject.

На SO можно посмотреть here и here, хотя эти два обсуждают асинхронные веб-запросы, а не команды SQL. Но проблема все-таки - выбор времени от асинхронной команды SQL/веб-запроса.

Предлагаемый подход заключается в вызове Task.Factory.FromAsync, а затем ThreadPool.RegisterWaitForSingleObject ожидания или таймаут на десктопе, соответствующем задаче.

Я ничего не понимаю здесь. Метод async IO использует обратный вызов порта ввода-вывода для возвращения с результатом. Когда начинается такая операция ввода-вывода, вызывающий поток возвращается обратно в пул потоков, который будет повторно использоваться другими запросами.

С другой стороны, в соответствии с MSDN:

Метод RegisterWaitForSingleObject очереди указанный делегат в пул потоков

и

Ждание нить использует Win32 Функция WaitForMultipleObjects для отслеживает зарегистрированные операции ожидания.

Это означает, что он блокирует поток потока нити, пока не вернется наш асинхронный IO или не произойдет тайм-аут. Если мое понимание правильное, то при выполнении N-асинхронных ИО будет блокировать и блокировать потоки пулов N потоков, если мы используем этот метод.

Но тогда в чем смысл использования async IO в этих условиях? Вся доброта IOCP убита RegisterWaitForSingleObject.

С другой стороны, в соответствии с this MSDN blog, RegisterWaitForSingleObject оптимизирует ожидания, дозирования несколько ручек из одной и той же нити в одном вызове WaitForMultipleObjects, который в свою очередь ограничено по отношению к количеству ручек он может ждать - а именно 64.

Итак, сколько потоков потоков нитей (b) заблокировано, если 65 асинхронных запросов ввода-вывода выполнены из одного потока в сочетании с RegisterWaitForSingleObject за каждый запрос?

+1

Это довольно подробно упоминается в сообщении в блоге «Он может поставить в очередь рабочий элемент, чтобы блокировать дескриптор, но это приведет к сжиганию потока ThreadPool для каждого такого вызова. Вместо этого ...» –

+0

Да, я был рад чтобы понять, что я правильно понял вопрос ** перед ** чтением сообщения. – mark

ответ

2

Итак, сколько потоков нитей потока (b) заблокировано, если 65 запросов асинхронного ввода-вывода сделаны из одного потока в сочетании с RegisterWaitForSingleObject для каждого запроса?

Два (для RegisterWaitForSingleObject вызовов) - каждый ThreadPool поток может обрабатывать 64 запросов (технически, это значение MAXIMUM_WAIT_OBJECTS, что 64 на практике).

Неужели последние не убивают полезность первого?

Нет. Это уменьшает его эффективность, но так как существует пул потоков в RegisterWaitForSingleObject, он не убивает полезность.

Обратите внимание, что в C# 5 я обычно использовал бы поддержку/await с таймаутом, чтобы справиться с этим. Task.Delay можно использовать для обработки этого просто, или вы можете сделать extension method using a Timer для обработки тайм-аутов на любом Task.