Таким образом, этот вопрос касается шаблона проектирования .Net IAsyncResult и необходимости вызова EndInvoke
, как описано в этом вопросе
Фон
У меня есть некоторый код, в котором я запускаю потенциально много асинхронных вызовов определенной функции, а затем жду завершения всех этих вызовов, прежде чем использовать EndInvoke()
для возврата всех результатов.
Вопрос 1
Я не знаю, встречался ли какой-либо из вызовов с исключением, пока я не вызову EndInvoke()
, и в случае, если исключение происходит в одном из вызовов, весь метод должен завершиться сбоем, и исключение будет включено в специфичный для API исключение и выбрасывание вверх.
Итак, мой первый вопрос: каков наилучший способ обеспечить правильное завершение оставшихся асинхронных вызовов?
Является ли блок finally
, который вызывает EndInvoke()
для оставшихся незавершенных вызовов (и игнорирует любые дальнейшие исключения), лучшим способом сделать это?
Вопрос 2
Во-вторых, когда я впервые запускаю все свои асинхронные вызовы, я затем вызываю WaitHandle.WaitAll()
в массиве WaitHandle
экземпляров, которые я получил из моих IAsyncResult
экземпляров. У метода, который запускает все эти асинхронные вызовы, есть тайм-аут для соблюдения, поэтому я предоставляю это методу WaitAll()
. Затем я проверяю, все ли вызовы завершены, если нет, то должен был быть достигнут тайм-аут, чтобы метод также завершился сбоем и выдал еще одно исключение, специфичное для API.
Итак, мой второй вопрос: что мне делать в этом случае?
Мне нужно позвонить EndInvoke()
, чтобы завершить все эти асинхронные вызовы, прежде чем я выдам ошибку, но в то же время я не хочу, чтобы код зависал, так как EndInvoke()
блокирует. Теоретически, по крайней мере, если время ожидания WaitAll()
истекло, то все асинхронные вызовы должны были сами превысить тайм-аут и выдать исключения (таким образом, завершив вызов), поскольку они также управляются тайм-аутом, но этот тайм-аут потенциально отличается от основного таймаута