2010-09-17 2 views
1

Я имею в виду this ответ, где говорится, что это не требуется, однако есть несколько конкретных предположений. Этот вопрос является общим.Требуется ли асинхронному вызову дополнительный поток в текущем процессе или использовать другой поток в пуле потоков?

  • Я использую C#
  • процесс Асинхронный ничего не делает, а просто вызов внешнего API и ждет ответа.
+0

Можете ли вы опубликовать некоторую информацию о интерфейсе для внешнего API? Ответ зависит от этого. «вызов внешнего API и ожидание ответа» звучит синхронно, поэтому разъяснение будет полезно. –

+0

Вы можете игнорировать «и ждать ответа». Под этим я просто подразумевал, что мы не выполняем какую-либо другую операцию (большой ресурс, потребляющий жесткий диск или сложный расчет) в том же процессе/той же системе. – IsmailS

ответ

3

Вообще-то да, но есть хотя бы одно исключение, о котором я могу думать. Чтобы инициировать асинхронную операцию, вы должны перенести операцию вне контекста вызывающего. Я имею в виду, что вызывающий абонент не должен блокировать ожидание завершения операции. То, что обычно означает, что операция должна перемещаться во вновь созданный поток, поток из ThreadPool, порт завершения ввода-вывода, другой процесс или тому подобное.

Я сказал, что было одно исключение, которое пришло на ум. Если мы немного извратим наше определение асинхронности, мы можем разрешить сценарии, в которых инициатор не блокирует ожидание завершения операции, фактически не перемещая операцию в другой поток. Лучшим примером этого является насос сообщений пользовательского интерфейса. В .NET достаточно просто вызвать Control.BeginInvoke из самого потока пользовательского интерфейса, чтобы опубликовать выполнение делегата в том же потоке. Инициатор явно не будет блокировать ожидание завершения делегирования, и все же делегат в конечном итоге начнет выполнение в том же потоке. Это определенно является извращением того, что мы обычно называем асинхронным, потому что в этом сценарии операция блокируется до тех пор, пока вызывающий абонент не завершит, а не наоборот.

+0

Не могли бы вы указать ссылку на исключение, которое вы предложили, если у вас есть, или если кто-то, кроме меня, сможет его проголосовать. – IsmailS

+0

@Ismail: документация MSDN для 'Control.BeginInvoke' произносит почти точно. Он даже упоминает, что вы можете вызывать 'BeginInvoke' из * той же * нити, размещающей элемент управления, и что делегат будет выполняться« асинхронно »в * этом * потоке. –

+0

Как я могу сделать подобное (например, без запуска нового потока) для вызова внешнего веб-сервиса? – IsmailS

2

Да, используется бассейн Thread. Но этот поток не висит вокруг ожидающего внешнего устройства. Поток повторно используется, и при завершении ввода-вывода вызывается нить (более новая).

См. I/O Asynchronous Completion на MSDN.

3

Ваш вопрос слишком общий. У Windows API есть специальная поддержка асинхронного ввода-вывода без использования потока, например, проверьте документы для ReadFile(). Аргумент lpOverlapped управляет этим. Функция ReadFileEx() позволяет указать обратный вызов завершения ввода-вывода. Это хорошо охватывает классы .NET framework.

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

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