Я недавно искал асинхронные вызовы. Я нашел указатель на статью с примером реализации IAsyncResult уважаемого автора Джеффри Рихтера. Изучив эту реализацию, я многое узнал о том, как работают асинхронные вызовы.
Вы также можете посмотреть, можете ли вы скачать и изучить исходный код для System.Runtime.Remoting.Messaging.AsyncResult
, который вас особенно интересует. Вот ссылка на инструкции о том, как это сделать в Visual Studio .
Чтобы добавить немного к хорошим ответам JaredPar ...
1: Я полагаю, что если вы определите замыкание, которое может быть присвоено переменной типа AsyncCallback (принимает IAsyncResult и возвращает void), оно должно работать так, как вы ожидаете, что замыкание будет работать в качестве этого делегата, но я не уверен, что могут быть проблемы с объемом. Исходная локальная область должна быть возвращена задолго до того, как будет вызван обратный вызов (именно это делает ее асинхронной операцией), так что имейте это в виду в отношении ссылок на локальные (стековые) переменные и их поведения. Я думаю, что ссылки на переменные-члены должны быть хорошими.
2: Я думаю из вашего комментария, что вы, возможно, неправильно поняли ответ на этот. В примере реализации Джеффри Рихтера дескриптор ожидания сигнализируется до обратного вызова. Если вы думаете об этом, это должно быть так. Как только он вызывает обратный вызов, он теряет контроль над выполнением. Предположим, что метод обратного вызова выдает исключение .... выполнение может откатиться назад за метод, который вызвал обратный вызов, и, таким образом, предотвратить последующий сигнал дескриптора ожидания! Таким образом, дескриптор ожидания должен быть сигнализирован перед вызовом обратного вызова. Они также намного ближе по времени, если выполняются в таком порядке, чем если бы они сигнализировали о дескрипторе ожидания только после возврата обратного вызова.
3: Как говорит JaredPar, IsCompleted должен возвращать true
до обратного вызова и до того, как будет обработан дескриптор ожидания. Это имеет смысл, потому что если IsCompleted имеет значение false, вы ожидаете, что вызов к EndInvoke
будет блокироваться, и весь смысл дескриптора ожидания (как с обратным вызовом) должен знать, когда результат готов, а не будет блок. Итак, сначала IsCompleted устанавливается на true
, затем сигнализируется дескриптор ожидания, а затем вызывается обратный вызов. Посмотрите, как пример Джеффри Рихтера делает это. Однако , вам, вероятно, следует избегать предположений о порядке, в котором эти три метода (опрос, дескриптор ожидания, обратный вызов) могут обнаружить завершение, поскольку их можно реализовать в другом порядке, чем ожидалось.
4: Я не могу вам помочь, за исключением того, что вы можете найти ответ, отладив исходный код фреймворка для реализации, которая вас интересует. Или, возможно, вы могли бы придумать эксперимент, чтобы выяснить ... или организовать хороший эксперимент и отладить исходный код фреймворка, чтобы быть действительно уверенным.