Поток WPF Dispatcher зависает часами, а затем автоматически восстанавливается - PullRequest
0 голосов
/ 24 января 2019

У меня очень сложное приложение пользовательского интерфейса WPF - клиент сообщил, что пользовательский интерфейс зависает в течение нескольких часов (от 13 до 20 часов), а затем восстанавливается автоматически.Я анализирую дамп памяти, а также отлаживаю приложение в VS2015.

Приношу свои извинения за длинное письмо, но нет другого способа объяснить проблему o / w.

  1. Я вижу много потоков при отладке в окне потоков - будетвсе эти потоки живут на время существования приложения, или некоторые из них являются временными и через некоторое время умрут, как объекты, которые будут собирать мусор в более позднее время?А как насчет тем с и тем с местоположением как ?enter image description here

  2. Я получаю данные из фонового режима, и мне приходится выполнять тяжелую работу в потоке пользовательского интерфейса. Я постоянно получаю данные из потока bkg (1 сообщение / сек)чтобы обработать данные, которые я вызываю updateDataGrid (полученные сообщения помещаются в очередь, и поток пользовательского интерфейса ожидает завершения updateDataGrid перед обработкой следующего сообщения).

    private void updateDataGrid(XElement mainrowelement)
            {
                if (mainrowelement != null)
                { System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate ()
                    {
                       //perform heavy lifting UI work here
                       if(dataGridUpdated)
                       { 
                       //Raise event from one control to another
                        AsyncRaiseOnDataGridUpdated(mainrowelement);
                       }
                    });
                 }
             }
    

В другом классе

private void OnDataGridUpdated(XElement mainrowelement)
 {
System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate ()
        {
          //perform some more UI work here
        });
 }

Когда я смотрю на потоки в отладчике VS, я вижу 2 рабочих потока в расположении DispatcherOperationEvent.WaitOne enter image description here

Вопрос:

2 (a) ПочемуЯ вижу 2 потока DispatcherOperationEvent.WaitOne?

2 (b) Предполагается, что Dispatcher является частью MainThread, почему создаются новые рабочие потоки?

2 (c) Являются ли эти временные потоки?

2 (d) Они блокируют друг друга?- Я спрашиваю об этом, потому что во время отладки я не вижу, что их существование каким-либо образом блокирует пользовательский интерфейс, но клиент сообщил о проблеме блокировки - дамп памяти показал трассировку стека из DispatcherOperationEvent.WaitOne - но проблема была восстановлена ​​автоматически через 13 часов - произошел инцидент3 раза на стороне клиента.

Полный стек вызовов для идентификатора потока 11872 из дампа памяти:

ntdll! NtWaitForMultipleObjects + ядро ​​KERNELBASE! WaitForMultipleObjectsEx + e832!+62 clr! Thread :: DoAppresponWaitWorker + 1e4 clr! Thread :: DoAppresponWait + 7d clr! WaitHandleNative :: CorWaitOneNative + 165 [[HelperMethodFrame_1OBJ] (System.Threading.WaitHandle.WaOOneNitOit.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.Wa.W.W.W.W.W)Runtime.InteropServices.SafeHandle, UInt32, Boolean, Boolean) mscorlib_ni! System.Threading.WaitHandle.InternalWaitOne (System.Runtime.InteropServices.SafeHandle, Int64, логический, булевый, системный.TimeSpan, Boolean) +49 WindowsBase_ni! System.Windows.Threading.DispatcherOperation + DispatcherOperationEvent.WaitOne () + 2f WindowsBase_ni! System.Windows.Threading.DispatcherOperation.Wait (System.TimeSpan) + 6b WindowsBase_ni! System.Windows.Th.InvokeImpl (System.Windows.Threading.DispatcherOperation, System.Threading.CancellationToken, System.TimeSpan) + WindowsBase_ni! System.Windows., System.Object, Int32) + 1f0 WindowsBase_ni! System.Windows.Threading.Dispatcher.Invoke (System.Windows.Threading.DispatcherPriority, System.Delegate) + 3e MyWPFApp.CustomDataGrid.updateDataGrid (System.Xml.Linq.XElement)eb

Полный стек вызовов для идентификатора потока 13952 из дампа памяти:

ntdll! NtWaitForMultipleObjects + ядро ​​KERNELBASE! WaitForMultipleObjectsEx + e8 + Wait32Explemplejectsb3 clr! WaitForMultipleObjectsEx_SO_TOLERANT + 62 clr! Thread :: DoAppresponWaitWorker + 1e4 clr! Thread :: DoAppresponWait + 7d clr! WaitHandleNative :: CorWaitOneNative + 165 [система HelperMethodFrame_itHite.Wa.We.We.We.We.Wa.W.W.W.W.Wa.W.W.W.W.W.Wa.Wa.W.W.W.W.W.WaitOneNative (System.Runtime.InteropServices.SafeHandle, UInt32, Boolean, Boolean)mscorlib_ni! System.Threading.WaitHandle.InternalWaitOne (System.Runtime.InteropServices.SafeHandle, Int64, Boolean, Boolean) + 1bThreading.DispatcherOperation + DispatcherOperationEvent.WaitOne () + 2f WindowsBase_ni! System.Windows.Threading.DispatcherOperation.Wait (System.TimeSpan) + 6b WindowsBase_ni! System.Windows.Threading.Dispatcher.InvokeImpl (System.Windows.Threading.Threading.CancellationToken, System.TimeSpan) + aa WindowsBase_ni! System.Windows.Threading.Dispatcher.LegacyInvokeImpl (System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32B )_1 Windows0.Windows.Threading.Dispatcher.Invoke (System.Windows.Threading.DispatcherPriority, System.Delegate) + 3e MyWPFApp.CustomControl.OnDataGridUpdated (System.Xml.Linq.XElement) + d6

1051 *

Спасибо,

РДВ

...