Главное приложение WPF перестает отвечать, если перемещается дочернее окно - PullRequest
2 голосов
/ 31 декабря 2010

У нас есть приложение, написанное на C # с использованием WPF.У него есть событие активации на основе таймера, которое приводит к некоторому рисованию в контексте DirectX.

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

Нормальная работа возобновляется с точногота же точка, где она замерзла, если нажать комбинацию клавиш ALT + TAB.В замороженном состоянии не происходит увеличения использования ЦП / памяти, что заставляет меня заподозрить какую-то блокировку основного потока.

Обычно, если мое приложение зависает в середине какой-либо операции, я быиди, нажмите паузу из Visual Studio, и увидеть представление потока в отладчике.Это дает мне достаточное представление о том, какой вызов является виновником.

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

Кто-нибудь сталкивался / знает о подобной проблеме, и о том, как я могу продолжить отладку?

Ответы [ 2 ]

1 голос
/ 01 января 2011

Проблема в том, что вы используете один поток. Вам нужно перенести работу в другой поток. то есть: ThreadPool.QueueUserWorkItem, либо используйте более новую модель задач, либо Dispatcher.Invoke ...

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

1 голос
/ 31 декабря 2010

Попробуйте использовать процесс BackgroundWorker для запуска таймера в фоновом режиме. У меня была точно такая же проблема, и я использовал BackgroundWorker, и она исправила мою проблему. Вот пример кода, с которого можно начать:

BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
bw.Dispose();

private void bw_DoWork(object sender, DoWorkEventArgs e)
  {
     //Do Stuff Here            
     return;
  }

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
     //Do an action when complete
  }

Просто оберните это в событие отметки таймера, и все должно работать как нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...