Так что этот вопрос касается шаблона дизайна .Net IAsyncResult и необходимости вызова EndInvoke
, как покрытый this вопросаДва вопроса по обеспечению EndInvoke() вызывается в списке IAsyncResult объекты
фона
У меня есть код, в котором я увольняю потенциально много асинхронных вызовов определенной функции, а затем ожидаю завершения всех этих вызовов до использования EndInvoke()
, чтобы вернуть все результаты.
Вопрос 1
Я не знаю, является ли какой-либо из вызовов столкнулся исключение, пока я не позову EndInvoke()
и в том случае, если исключение происходит в одном из вызовов весь метод должен сбой и исключение обернуто в конкретное исключение API и отбрасывается вверх.
Итак, мой первый вопрос - это лучший способ, чтобы гарантировать, что оставшаяся часть асинхронных вызовов будет правильно завершена?
Это блок finally
, который вызывает EndInvoke()
на оставшуюся часть неисполненных вызовов (и игнорирует любые дополнительные исключения), лучший способ сделать это?
Вопрос 2
Во-вторых, когда я первый выпалить все мои asyc звонки Затем я называю WaitHandle.WaitAll()
на массив WaitHandle
экземпляров, которые я получил от моих IAsyncResult
экземпляров. Метод, который запускает все эти асинхронные вызовы, имеет тайм-аут для привязки, поэтому я предоставляю это методу WaitAll()
. Затем я проверяю, завершены ли все вызовы, если нет, тогда должен быть достигнут тайм-аут, поэтому метод также должен потерпеть неудачу и выбросить другое конкретное исключение API.
Итак, мой второй вопрос: что мне делать в этом случае?
Мне нужно позвонить EndInvoke()
, чтобы завершить все эти асинхронные вызовы до того, как я сброшу ошибку, но в то же время я не хочу, чтобы код застревал, поскольку EndInvoke()
блокирует. Теоретически, по крайней мере, если вызов WaitAll()
истекает, все асинхронные вызовы сами должны иметь тайм-аут и исключать исключения (таким образом, завершая вызов), поскольку они также регулируются таймаутом, но этот тайм-аут потенциально отличается от основного таймаута
Любые ссылки или примеры кода для этого? – RobV
См. Раздел «Обертка APM операций в задаче» на этой странице MSDN (http://msdn.microsoft.com/en-us/library/dd997423.aspx). –
Ах, .NET 4.0 не является вариантом, так как API должен оставаться на 3.5, поскольку мы создаем для MS и Mono и Mono 4.0 не достаточно стабильна, чтобы рассмотреть возможность перехода к этой миграции в это время – RobV