2010-09-13 4 views
1

В настоящее время я работаю над приложением WPF/C#, которое подключено к внешней камере. Это приложение получает снимок с камеры, затем выполняет некоторый анализ и отображает его на экране через пользовательский интерфейс. На интерфейсе также много других элементов интерфейса (таких как кнопки, меню и выпадающие списки). Прямо сейчас, пока приложение запущено, пользовательский интерфейс заметно замедлился - например, выпадающее поле со щелчком мыши может замерзнуть всего за секунду до открытия. Затем он может снова заморозить, прежде чем позволить пользователю выбрать значение. Я уверен, что это связано с тем, что моментальный снимок происходит в том же потоке, что и весь пользовательский интерфейс, однако я очень наивна из-за правильного использования потоков и действительно теряю всю полноту, так как я могу правильно исправить эту проблему , В принципе, я хочу, чтобы пользовательский интерфейс не был замечен медленнее, даже несмотря на то, что самая быстрая загрузка изображений, по-видимому, составляет около 1/секунды от камеры. Как я могу разделить это на несколько потоков? И это даже поможет моей проблеме? Спасибо; любая помощь глубоко ценится.Снижение моментального снимка Пользовательский интерфейс - требуется резьба?

+0

С простой современной веб-камерой 640x480 через USB я получаю 18 кадров в секунду (в C#). Даже со старой камерой (с 2003 года) я получаю 12 кадров в секунду. Может быть, у вас проблема конфигурации? – egrunin

+0

Я фактически не пользуюсь веб-камерой, а скорее камерой внутри очень большого, старого инструмента. Я получаю снимок «рекомендуется» с использованием API-интерфейса производителя, и это все еще возможно. – JToland

ответ

3

Если вы не используете .NET 4, вы можете использовать BackgroundWorker.

BackgroundWorker worker = new BackgroundWorker(); 

worker.DoWork += (s, e) => 
{ 
    // Perform things on the background thread here. 
}; 
worker.RunWorkerCompleted += (s, e) => 
{ 
    // Code to be run after the thread is done, on the UI-thread. 
}; 
worker.RunWorkerAsync(); 
+0

Если у меня есть объект из потока пользовательского интерфейса (в частности, объект Image), могу ли я установить его равным e.Result в методе RunWorkerCompleted? У меня есть это сейчас, я вызываю ошибку, потому что говорит, что я пытаюсь получить доступ к объекту из другого потока в RunWorkerCompleted. Какой еще способ установить объект Image? – JToland

+0

Да, если вы установите e.Result в DoWork, вы должны иметь возможность назначить myVar = e.Result в коде RunWorkerCompleted; который работает на UI-потоке и не должен запускать ошибку поперечного потока. – Jeremy

+0

Но это так. У меня есть объект TransformedBitmap, CurrentImage, который является свойством моего окна MainForm и фактически связан с объектом Image (он сконструирован таким образом, что когда я устанавливаю CurrentImage на что-то, объект Image, отображаемый в пользовательском интерфейсе, сам обновляется до самого нового изображения). Прямо сейчас, когда я говорю это. CurrentImage = (TransformedBitmap) e.Result ;, я получаю ошибку поперечного потока. Я читал о BackgroundWorkers в течение нескольких часов, и я не могу на всю жизнь понять, почему у меня такие проблемы ... – JToland

1

Если у вас есть доступ к .NET 4, вы можете настроить Task для получения моментального снимка и continuation для обновления графического интерфейса. Задача будет выполняться в потоке пула потоков, оставляя ваш пользовательский интерфейс отзывчивым. Не забудьте использовать планировщик FromCurrentSynchronizationContext для продолжения.

var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext; 
var task = Task.Factory.StartNew(() => { // Get snapshot }) 
    .ContinueWith(t => { // update ui }, uiScheduler); 
+0

К сожалению, я вынужден написать это с помощью .NET 3.5. – JToland

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