У меня есть многопоточное приложение WPF на C#, которое является плагином для более крупного программного обеспечения (Princeton Instruments LightField, для тех, кто заинтересован).C# WPF-зависимые проблемы параллелизма
Мой плагин вызывает синхронный метод в потоке, отдельно от графического интерфейса. Этот метод основан на API-интерфейсе камеры и фиксирует n-секундную экспозицию от камеры и возвращает захваченный кадр.
ситуация выглядит примерно так:
private static volatile bool _STOP = true;
// Runs when the "Run" button is clicked
private void Run_Click(object sender, RoutedEventArgs e)
{
object time = InputTime.Text; // a non-negative integer provided by the user
_STOP = false;
Thread run_thread = new Thread(Running);
run_thread.Start(time);
}
// Runs when the "Stop" button is clicked
private void Stop_Click(object sender, RoutedEventArgs e)
{
_STOP = true;
}
// Separate Thread from GUI
private void Running(object t)
{
int time = Convert.ToInt32(t);
FrameObject f;
while(!_STOP)
{
// synchronously capture a t-second exposure
f = CameraAPI.CaptureImage(t);
// display the exposure on a viewer controlled by the parent thread
Application.Current.Dispatcher.BeginInvoke(new Action(Viewer.Display(f));
}
}
Этот код (или, скорее, это более сложный родственный) отлично работает на компьютере, я разработал его (Computer A). Я нажимаю «Выполнить», и все приложение остается отзывчивым во время работы кода.
Когда я пытаюсь запустить его на компьютере, где он будет проходить регулярно (Computer B), однако, появляется следующее поведение:
- При нажатии на кнопку Run, графический интерфейс перестает отвечать на запросы при п секунд (n - время, отправленное методу
CameraAPI.CaptureImage(n);
). Это происходит для любого положительного целого числа n и продолжается как , в то время как цикл выполняет этот метод каждый цикл цикла (то есть приложение замерзает в течение n секунд, при вызове метода отображения имеется короткий незамерзающий момент, а затем приложение снова замораживается для n секунд). - Если я позвоню
Thread.Sleep(n);
вместоCameraAPI.CaptureImage(n);
, приложение не замерзает. - Это не только мой плагин, который зависает - это все приложение.
- Я построил, перестроил, удалил и переписал свой код с компьютера A на компьютер B, и ошибка сохраняется.
- Компьютер A (где я его построил) идентичен (насколько я нашел) компьютеру, имеющему проблемы (компьютер B). Процессоры, ОС, диски, оперативная память, версии приложений и т. Д. Все те же. Компьютер A специально существует, так что приложения могут быть разработаны для Компьютер B.
- Удаление линии
Application.Current.Dispatcher.BeginInvoke(new Action(Viewer.Display(f));
не останавливает замораживание GUI. Это не проблема. - Приложение использует то же количество потоков (43) на каждом компьютере. Когда подключаемый модуль работает, количество потоков увеличивается на одну и ту же величину (1-4 в зависимости от того, где в нашей программе) на каждом компьютере.
Итак, на двух, казалось бы, одинаковых системах один и тот же код имеет разные результаты. В системе A он работает по назначению (без зависания GUI), а в системе B графический интерфейс всего приложения - не только плагина, который я пишу, - зависает каждый раз, когда вызывается синхронный метод.
Это поведение ошибки превышает мое понимание компьютеров, поэтому теперь я здесь. Любые идеи относительно того, что вызывает это различие в поведении?