2015-08-26 4 views
-1

Я создал приложение WCF, и в нескольких местах я использую BeginInvoke для асинхронного запуска методов. В некоторых местах он асинхронен, а в других - синхронно. Поскольку система довольно сложная, я надеялся просто бросить этот вопрос высокого уровня там, надеясь, что кто-то знает причину, по которой BeginInvoke будет вынужден работать синхронно.Почему мой BeginInvoke работает синхронно

Возможные причины я Рассмотренные и считают, не являются причиной:

  • Я выбежал из Threadpool темы - Я думаю, что на пике я использую менее 20 потоков.
  • Я использую блокировки через эти потоки останавливая их одновременно расстрелы - синхронизация не используется, так как каждый вызов к методу на отдельном WCF ServiceHost
  • асинхронного метод родительского (который определенно работает асинхронно) вызывает много детей BeginInvokes и вас не может встраивать асинхронные вызовы - я не думаю, что это ограничение
  • Родительский асинхронный метод сам по себе является частью WCF ServiceHost, который является InstanceContextMode.PerSession, и есть некоторые ограничения на его вложение асинхронных вызовов. Опять же, я не знаю Так думает, но FYI
  • Каждый вызываемый ребенок является (отличным от родителя) WCF ServiceHost, метод которого я звоню, является инстансом e того же ServiceType и запускается как InstanceContextMode.Single и ConcurrencyMode.Single. - Значит ли это каким-то образом удара при вызове подпрограммы из работы тех асинхронно (я не понимаю, почему это было, но на всякий случай)

Любые идеи/решения очень ценятся

+0

Можете ли вы рассказать нам, как вы пришли к выводу, что они работают синхронно? Возможно, вызывающий поток блокируется во время их завершения? –

+5

'BeginInvoke' - это« широкое имя ». К какому BeginInvoke вы имеете в виду? 'Control.BeginInvoke'? 'Delegate.BeginInvoke'? 'Dispatcher.BeginInvoke'? или другой? Следующий вопрос - какие потоки используются, я имею в виду, какой поток (ы) вызывает его и какие потоки являются целями? любые контексты синхронизации используются? пользовательские потоки с сообщениями или без? Задачи или библиотека TPL?Пользовательские диспетчеры или планировщики? (....) на самом деле, обрезка и показ кода может быть быстрее, чем опросить вас за подробностями. – quetzalcoatl

+0

Ron Beyer: код не блокируется, он использует проверку IsCompleted в цикле, чтобы увидеть, когда вызывать EndInvoke. Я знаю, что это синхронно, потому что я допрашиваю статус звонков каждые 10 секунд, и я вижу из журналов, что все эти опросы происходят до того, как мой код сможет проверить первый статус IsCompleted. – pogpogoSE

ответ

2

Я хотел бы ссылаться на эту цитату относительно Delegate.BeginInvoke от Джо Даффи в своей книге Параллельное программирование на Windows:

Все типы делегата, по соглашению предлагают метод BeginInvoke и EndInvoke наряду с обычным синхронным методом Invoke. Хотя это хорошая функция модели программирования, вы должны держаться подальше от них, где это возможно. В реализации используется удаленная инфраструктура, которая накладывает значительные ажурные накладные расходы на асинхронный вызов. Работа в очереди в пуле потоков напрямую часто является лучшим подходом, хотя это означает, что вам нужно координировать логику рандеву самостоятельно.

Я уже делал свои собственные тесты, и накладные расходы могут составлять много секунд при частом использовании. Возможно, это не ответ на ваш вопрос, потому что было бы почти невозможно, я думаю, не видя и не отлаживая код. Это скорее предположение, что вы должны еще раз взглянуть на ваш подход. Возможно, работа в очереди на ThreadPool напрямую или с помощью TPL (Ожидание задачи/async &).

Если вы все еще пытаетесь найти проблему с текущим кодом, а не пересматриваете его для лучшей стратегии, и вам все равно нужна помощь, вы должны найти способ воспроизвести свои симптомы (что он работает синхронно) и Предоставьте код, подтверждающий это.

+0

Я знаю, что код идеален, но я действительно надеялся на то, что другие люди столкнулись с этим, что может вызвать его. Если нет, то требуется другой подход. Накладные расходы при вызове кажутся довольно маленькими, так как я запускаю один и тот же код на быстродействующем методе перед кодом, который я описал, и это очень быстро. Цель этой последовательности - обеспечить синхронизированное обновление данных. Первый шаг подготавливается к нему, и второй шаг выполняется до тех пор, пока ни одна из служб не обнаружила никаких проблем. Подготовка происходит очень быстро. – pogpogoSE

Смежные вопросы