AsyncCallBack завершен синхронно
Недавно я заметил следующий шаблон, но я не полностью понимаю использование свойства CompletedSynchronously:
IAsyncResult channelOpenResult = channel.BeginOpen(new AsyncCallback(OnOpenCompleteChannel), channel);
if (channelOpenResult.CompletedSynchronously)
{
CompleteOpenChannel(channelOpenResult);
}
И снова в обратном вызове:
void OnOpenCompleteChannel(IAsyncResult result)
{
if (result.CompletedSynchronously)
return;
else
CompleteOpenChannel(result);
}
А где-то в коде есть, конечно, функция:
void CompleteOpenChannel(IAsyncResult result) ...
Является ли это способом обработки асинхронного вызова по-разному в зависимости от того, выполняется ли он напрямую или нет? Но зачем использовать его в этом случае, поскольку AsyncCallback всегда будет вызван (будет?)?
Может ли кто-нибудь привести пример, когда вызов выполняется синхронно?
Ответы
Ответ 1
Смотрите этот блог. Обычный шаблон выполняет асинхронную работу в цикле и проверяет, что CompletedSynchronously помогает избежать случая, когда вы получаете "несчастливый", и куча асинхронных вызовов происходит для завершения синхронизации, и вы рискуете StackOverflowException. (Например, если вы читаете данные по сети, и данные, которые вы читаете, уже прошли через провод и буферизированы, ваш асинхронный вызов может завершиться синхронно, что означает, что ваш обратный вызов вызывается в той же теме (с более высоким стек), что означает, что вам лучше не планировать другой асинхронный вызов в цикле.)
Ответ 2
В соответствии с этим document вы можете предоставить вызов с синхронным обратным вызовом ASync и только в том случае, если вызов не обрабатывается синхронно, он вызывает методы ASync. Я не думаю, что это действительно применимо к Silverlight (потому что все запросы Silverlight ASync до некоторой степени), но, вероятно, больше используются для пользовательских фабрик в других .NET-приложениях.
Надеюсь, что это поможет.