我有一个非常复杂的WPF UI应用程序-客户报告说UI会挂起几个小时(约13至20小时),然后自动恢复。我分析内存转储以及在VS2015中调试应用程序。
我很抱歉收到一封冗长的电子邮件,但没有其他方法可以解释这个问题。
我在线程窗口中进行调试时看到许多线程-这些线程是否全部生存于应用程序的生命周期中,还是有些是瞬态的,并且会在一段时间后像对象在以后被垃圾回收时那样消失?带有<无名称>的线程和具有<不可用>位置的线程呢?
我从后台获取数据,并且必须在UI线程中进行一些繁重的工作 我一直在从bkg线程(每秒1条消息)中获取数据,以处理我称为updateDataGrid的数据(接收到的消息已排队,UI线程在处理下一条消息之前等待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调试器中查看线程时,我在DispatcherOperationEvent.WaitOne位置看到2个Worker线程。
问题:
2(a)为什么我看到2个DispatcherOperationEvent.WaitOne线程?
2(b)分派器应该是MainThread的一部分,那么为什么要创建新的辅助线程?
2(c)这些是瞬态线程吗?
2(d)这些互相阻塞吗? -我问这个问题是因为在调试时我没有看到它们的存在以任何方式阻止了UI,但是客户报告了阻止问题-内存转储显示了来自DispatcherOperationEvent.WaitOne的堆栈跟踪-但问题在13小时后自动恢复-发生了事件在客户端3次。
来自内存转储的线程ID 11872的完整调用堆栈:
ntdll!NtWaitForMultipleObjects + a KERNELBASE!WaitForMultipleObjectsEx + e8 kernel32!WaitForMultipleObjectsExImplementation + b3 clr!WaitForMultipleObjectsEx_SO_TOLERANT + 62 clr!Thread :: DoAppropriateWaitWorker + 1e4 clr!Thread :: DoAppropriateWait + 7d clr!WaitHandleNative :: CorWaitOneNative + 165 [[HelperMethodFrame_1OBJ] (System.Threading.WaitHandle.WaitOneNative)] System.Threading.WaitHandle.WaitOneNative(System.Runtime.InteropServices.SafeHandle, UInt32,布尔值,布尔值) mscorlib_ni!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle, Int64,布尔值,布尔值)+ 1b mscorlib_ni!System.Threading.WaitHandle.WaitOne(System.TimeSpan, 布尔值)+49 WindowsBase_ni!System.Windows.Threading.DispatcherOperation + DispatcherOperationEvent.WaitOne()+ 2f WindowsBase_ni!System.Windows.Threading.DispatcherOperation.Wait(System.TimeSpan)+ 6b WindowsBase_ni!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherOperation, System.Threading.CancellationToken,System.TimeSpan)+ aa WindowsBase_ni!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan,System.Delegate,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
内存转储中线程ID 13952的完整调用堆栈:
ntdll!NtWaitForMultipleObjects + a KERNELBASE!WaitForMultipleObjectsEx + e8 kernel32!WaitForMultipleObjectsExImplementation + b3 clr!WaitForMultipleObjectsEx_SO_TOLERANT + 62 clr!Thread :: DoAppropriateWaitWorker + 1e4 clr!Thread :: DoAppropriateWait + 7d clr!WaitHandleNative :: CorWaitOneNative + 165 [[HelperMethodFrame_1OBJ] (System.Threading.WaitHandle.WaitOneNative)] System.Threading.WaitHandle.WaitOneNative(System.Runtime.InteropServices.SafeHandle, UInt32,布尔值,布尔值) mscorlib_ni!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle, Int64,布尔值,布尔值)+ 1b mscorlib_ni!System.Threading.WaitHandle.WaitOne(System.TimeSpan, 布尔值)+49 WindowsBase_ni!System.Windows.Threading.DispatcherOperation + DispatcherOperationEvent.WaitOne()+ 2f WindowsBase_ni!System.Windows.Threading.DispatcherOperation.Wait(System.TimeSpan)+ 6b WindowsBase_ni!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherOperation, System.Threading.CancellationToken,System.TimeSpan)+ aa WindowsBase_ni!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan,System.Delegate,System.Object,Int32)+ 1f0 WindowsBase_ni!System.Windows.Threading.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority, System.Delegate)+ 3e MyWPFApp.CustomControl.OnDataGridUpdated(System.Xml.Linq.XElement)+ d6
谢谢
RDV