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

Что произойдет, если асинхронный вызов делегата не вернется?

Я нашел достойный пример того, как асинхронно вызывать делегат с таймаутом... http://www.eggheadcafe.com/tutorials/aspnet/847c94bf-4b8d-4a66-9ae5-5b61f049019f/basics-make-any-method-c.aspx. В итоге он использует WaitOne с таймаутом, чтобы определить, не вызывается ли вызов до истечения таймаута.

Я также знаю, что вы должны иметь EndInvoke для соответствия каждому BeginInvoke.

Итак, что произойдет, если истечет время ожидания ожидания? Мы (предположительно) НЕ хотим вызывать EndInvoke, поскольку это блокирует. Код может продолжать делать "другие вещи", но мы что-то пропустили? Есть ли какая-то бедная нить где-то заблокированная, ожидающая возвращения, которая никогда не произойдет? Пропустили ли мы какую-то память, где будет размещен результат-то-будет-никогда-возврат?

4b9b3361

Ответ 1

Я думаю, этот сообщение об этом очень хорошо:

Из сообщения:

Вы не можете завершить исполняемый делегат async, если это не ваш поток, но вы можете, если он есть. Если вы используете общие методы типа BeginInvoke, вы получаете поток потока потоков, управляемый инфраструктурой. Если вы используете класс Thread(), вы получаете собственный поток для управления, запуска, приостановки и т.д., Как вам нравится.

Разработка асинхронно требует, чтобы кто-то решил, кто будет управлять потоками. Многие различные методы, выполняемые асинхронно, используют потоки ThreadPool за кулисами.

Поскольку вы не можете/не должны прерывать поток пула потоков, тогда вы должны разработать код для связи с потоком, чтобы он мог выйти. Примеры MSDN для компонента BackgroundWorker демонстрируют такую ​​связь.

Иногда ваш код может блокировать поток, ожидающий ввода-вывода. Здесь вы обычно будете использовать несколько объектов ожидания, ожидая ввода-вывода или для ManualResetEvent.

Итак, вам нужно найти способ самостоятельно управлять потоками, если есть возможность тайминга, и вы хотите, чтобы поток был завершен.

Ответ 2

Вам нужно вызвать EndInvoke().

Вот ссылка, говорящая о том, что происходит с EndInvoke():

Является ли EndInvoke() опциональным, сортировка необязательной или определенно необязательной?

Вот ссылка в статью в принятом ответе.

Мы все говорили о технике "огонь и забыть" с асинхронным вызовом делегата на различных общественных форумах. Многие инструкторы DevelopMentor написали статьи и пример кода, показывающие технику, и мы все это описали в классе. И, конечно же, к тому времени это было и в книге Дона. Поэтому, когда Microsoft в конце концов вспомнила, чтобы позволить внешнему миру понять, что эта техника на самом деле не законна, это было довольно удивительно.

Ссылка MSDN на асинхронный шаблон.

Ответ 3

Вы будете утечка ресурсов, хранящихся в потоке. Будут различные биты удаленных объектов .NET, таких как AsyncResult. Несколько неуправляемых ручек, связанных с потоком. Все арахис по сравнению с одним мегабайтом адресного пространства виртуальной памяти, которое вы просочитесь, удерживается стекю потоков.

Вы никак не можете прервать нить, утечка будет постоянной. Когда вам приходится иметь дело с таким образом плохого поведения, ваш единственный хороший ресурс состоит в том, чтобы запустить его в отдельном процессе, чтобы вы могли заставить Windows очистить шрапнель, когда вы снимаете процесс в голове с помощью Process.Kill(). Даже это не гарантируется, такие зависания, как правило, связаны с неверными драйверами устройств. Process.Kill не завершит нить драйвера устройства. Легко видеть: попытка прервать процесс с помощью Taskmgr.exe заставит его работать с одной ручкой. У вас есть какая-то надежда, если этого не произойдет.