Могу ли я ускорить обратные вызовы из C ++ Dll в C #? - PullRequest
3 голосов
/ 03 марта 2011

Мы реализовали функциональность нашего основного кода в C ++ Dll, а затем написали C # UI поверх. В большинстве случаев это работает нормально, но в тех областях, где мы хотим, чтобы пользовательский интерфейс сообщал о прогрессе функции в C ++, у нас возникают некоторые проблемы с производительностью.

Мы передаем указатель на функцию C # в Dll, чтобы использовать ее для обновления прогресса. Когда он вызывается, мы используем InvokeRequired и Invoke (), чтобы убедиться, что обратный вызов является поточно-ориентированным. Измеряется со стороны C ++, это может занять от 16 мс до 180 мс. Есть ли способ сократить время, которое это занимает?

Один из этих обратных вызовов передает местоположение линии, которая должна быть нарисована на экране. Этот рисунок в настоящее время очень медленный - я предполагаю, что вызванные функции стоят в очереди и требуют времени для рисования в C #. Я вижу два способа борьбы с этим: 1. Измените функцию обратного вызова, чтобы отправить список строк и разрешить очереди стоять в очереди в C ++, ожидая завершения предыдущего вызова в C #. 2. Добавление линий в очередь на C # (желательно без вызова Invoke), а затем отрисовка всех доступных линий одновременно. Любые предложения о том, как это сделать, требуются ли оба варианта или альтернативные методы?

Спасибо за любую помощь.

Ответы [ 3 ]

3 голосов
/ 03 марта 2011

Вы можете использовать BeginInvoke вместо Invoke. Invoke ожидает возврата функции, в то время как BeginInvoke позволяет функции работать параллельно текущей нити.

1 голос
/ 03 марта 2011

Ваша проблема не в обратном вызове, а в вероятности вызова.Вызов - потенциально дорогая операция.Если вы меняете тему там, это займет время.Много.Вы также помещаете операции рисования в один и тот же поток, поэтому обратный вызов блокируется до тех пор, пока они не будут завершены.

Что вы можете сделать:

  • BeginInvoke - в основном обратный вызов прерывается раньше,рисование выполняется другим потоком.
  • Сократите количество вызовов, в основном, пакетных запросов.Это может быть сделано ВНЕ DLL C ++ - обратный вызов помещает corodinates в очередь, затем очередь в отдельном потоке вызывает BeginInvoke.

По сути, ваш однопоточный пользовательский интерфейс и требование переключения потоковчерез диспетчера убью вас, полностью в области C #.

В конце ваш вопрос сформулирован плохо.C ++ & C # не имеет ничего общего с проблемой, у вас будет такая же проблема только с C #.У вас есть API, выполняющий обратные вызовы в пользовательском интерфейсе, который должен переключать потоки (Invoke) и выполнять операции пользовательского интерфейса, и это приводит к тому, что обратный вызов занимает больше времени, чем вы хотите.Замените C ## на Smalltalk, Ассемблер, C #, Visual Basic, и проблема останется на 100% такой же.

0 голосов
/ 03 марта 2011

Насколько я понимаю ваш вопрос, есть только одна линия, которая должна быть нарисована.Но его координаты часто генерируются в неуправляемой части и отправляются в C # для обновления графического представления?Рассмотрите возможность включения метода рисования для отмены самого себя.Поэтому, когда - при рисовании линии - появляются новые координаты, отмените текущую линию и просто нарисуйте новые координаты.Таким образом, вы можете избавиться от необходимости создавать какие-либо очереди вообще.

@ Редактировать: Я склоняюсь к предложению лучше запросить все необходимые данные из части C ++ с помощью C #.Похоже, вы очень часто перезваниваете в .NET, чтобы контролировать визуальный вывод.Но это должно быть сделано из .NET (который знает намного лучше, как часто это вообще возможно).Таким образом, запрос всех данных из C ++ в определенной пользователем структуре может помочь.

...