PresentationFramework.dll的NullReferenceException

时间:2013-04-26 21:47:45

标签: wpf windows-8 datagrid

我正在使用一个奇怪的NullReferenceException,它显然是从GetNameCore()类的ItemAutomationPeer函数触发的。

异常的详细信息如下,但真正有趣的方面是它不会出现在运行Windows 7的开发机器或我们测试过的其他Windows 7计算机上。它只发生在我的Windows 8 Pro测试机上。

尝试编辑WPF DataGrid控件中的单元格时,显然会抛出异常。

我一直在努力追踪它,但没有成功。我尝试使用Visual Studio远程调试进程并单步执行代码,但是没有任何用户代码似乎触发异常。它显然是由PresentationFramework.Dll中的一系列事件执行的,异常只是通过AppDomain冒泡并最终导致应用程序崩溃。

如果有人能够想到任何可能导致这种情况发生的事情,或者找到解决问题的方法,那将会非常有帮助。

Exception Type:         System.NullReferenceException
Exception Message:  Object reference not set to an instance of an object.
Method Information: System.String GetNameCore()
Exception Source:   PresentationFramework

Stack Trace
  at System.Windows.Automation.Peers.ItemAutomationPeer.GetNameCore()
  at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
  at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
  at System.Windows.Automation.Peers.AutomationPeer.UpdateSubtree()
  at System.Windows.ContextLayoutManager.fireAutomationEvents()
  at System.Windows.ContextLayoutManager.UpdateLayout()
  at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
  at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
  at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
  at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object    resizedCompositionTarget)
  at System.Windows.Media.MediaContext.AnimatedRenderMessageHandler(Object resizedCompositionTarget)
  at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
  at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
  at System.Windows.Threading.DispatcherOperation.InvokeImpl()
  at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
  at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
  at System.Windows.Threading.DispatcherOperation.Invoke()
  at System.Windows.Threading.Dispatcher.ProcessQueue()
  at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
  at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
  at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
  at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
  at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
  at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
  at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
  at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
  at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
  at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
  at System.Windows.Threading.Dispatcher.Run()
  at System.Windows.Application.RunDispatcher(Object ignore)
  at System.Windows.Application.RunInternal(Window window)
  at System.Windows.Application.Run(Window window)
  at System.Windows.Application.Run()

4 个答案:

答案 0 :(得分:13)

经过远程调试器的大量反复,以及几乎无效的在线搜索后,我能够将问题追踪到几个行为不端的ItemAutomationPeer个实例。

当我遇到这个问题时,我对 UI Automation 及其在WPF框架中的支持方面一无所知。事实上,当 AutomationPeer 由于某种原因让我想到COM互操作时,我一会儿就追错了问题。如果您正在阅读本文并且不知道可能启动的UI自动化herehere可能会让您了解UI自动化在WPF上下文中的含义。

在我的情况下,事实证明应用程序在Windows 8测试计算机上崩溃但它在我的开发机器上工作正常(以及它已被部署到的无数其他计算机)的原因是Windows 8机器运行某种UI辅助功能应用程序(或其他一些UI自动化客户端)。一旦我在Windows 7开发机器上启动了Narrator应用程序,我就能让应用程序崩溃一样..

一旦我理解了根问题,我仍然无法进一步调试这个以确切地找出导致问题的控件,但更多在线阅读似乎指向自定义控件的大致方向,因此我开始了一个消除过程确定哪些自定义WPF控件有罪。我发现了两个自定义控件 - 一个扩展了DataGrid,另一个扩展了ListBox。

最后,我的问题的解决方案是创建扩展ItemsControlAutomationPeer基类的自定义类,并通过覆盖{{3}在每个自定义控件上提供这些自定义控件的问题。方法。

protected override AutomationPeer OnCreateAutomationPeer()
{
    return new ControlSpecificCustomAutomationPeer(this);
}

ControlSpecificCustomAutomationPeer类可能至少看起来像这样:

public class ControlSpecificCustomAutomationPeer
    : ItemsControlAutomationPeer
{
    public ControlSpecificCustomAutomationPeer(ItemsControl owner)
        : base(owner)
    {
    }

    protected override string GetNameCore()
    {
        return "";                         // return something meaningful here..
    }

    protected override ItemAutomationPeer CreateItemAutomationPeer(object item)
    {
        return new CustomDummyItemAutomationPeer(item, this);
    }             
}

public class CustomDummyItemAutomationPeer
    : System.Windows.Automation.Peers.ItemAutomationPeer
{
    public CustomDummyItemAutomationPeer(object item, ItemsControlAutomationPeer itemsControlAutomationPeer)
        : base(item, itemsControlAutomationPeer)
    {
    }

    protected override string GetNameCore()
    {
        if (Item == null)
            return "";            

        return Item.ToString() ?? "";
    }

    protected override AutomationControlType GetAutomationControlTypeCore()
    {
        return System.Windows.Automation.Peers.AutomationControlType.Text;
    }

    protected override string GetClassNameCore()
    {
        return "Dummy";
    }
}

答案 1 :(得分:1)

答案 2 :(得分:0)

我选择捕获错误并将其作为“非致命”错误进行处理。

private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    if (e.Exception.Source?.ToString() == "PresentationFramework")
    {
        e.Handled = true;
        Postgres.LogException(e.Exception, false);
        return;
    }

    HandleException(e.Exception);
    e.Handled = true;
    Shutdown();
}

答案 3 :(得分:0)

对我来说,此问题可以通过打开“讲述人”并在使用VirtualizationMode设置为“ Recycling”的虚拟化的树状视图中滚动来可靠地重现。将其设置为“标准”对性能的影响很小,但是崩溃不再发生。