创建窗口xaml时出现nullreferenceexception

本文关键字:nullreferenceexception 窗口 xaml 创建 | 更新日期: 2023-09-27 18:21:37

我的WPF应用程序有一个问题,它实际上有两个窗口,一个登录窗口和一个仪表板窗口,当我加载这些窗口时,我会间歇性地得到null引用异常。一个典型的异常看起来像这样(dashbaord)

Application: BlitsMe.Agent.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.NullReferenceException
Stack:
at System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Insert(System.__Canon, System.__Canon, Boolean)
at MS.Internal.AppModel.ResourceContainer.GetResourceManagerWrapper(System.Uri,  System.String ByRef, Boolean ByRef)
at MS.Internal.AppModel.ResourceContainer.GetPartCore(System.Uri)
at System.IO.Packaging.Package.GetPart(System.Uri)
at System.Windows.Application.LoadComponent(System.Object, System.Uri)
at BlitsMe.Agent.UI.WPF.Dashboard..ctor(BlitsMe.Agent.BlitsMeClientAppContext)
at BlitsMe.Agent.BlitsMeClientAppContext.RunDashboard()
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,  System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()

这是一个模糊的错误。在loadcomponent类的深处。

我在我的主AppContext类中使用两个方法启动我的仪表板,如下所示

    internal void SetupAndRunDashboard()
    {
        if (DashboardUiThread == null)
        {
            DashboardUiThread = new Thread(RunDashboard) { Name = "dashboardUIThread" };
            DashboardUiThread.SetApartmentState(ApartmentState.STA);
            DashboardUiThread.Start();
        }
    }
    private void RunDashboard()
    {
        UIDashBoard = new Dashboard(this);
        Dispatcher.Run();
    }

我的仪表板构造函数看起来像这个

public partial class Dashboard : Window
{
    public Dashboard(BlitsMeClientAppContext appContext)
    {
        this.InitializeComponent();
        ......
    }
}

我真的很感谢在这方面的帮助,因为我真的被难住了,因为空引用是在windows API的深处被抛出的。

创建窗口xaml时出现nullreferenceexception

好的,所以我发现了正在发生的事情,尽管在相当高的级别上,但似乎我不能同时启动2个ui。正如我在问题中所说,我运行登录ui和仪表板ui,并以上述方式启动它们,即启动一个STA Apartment状态的线程,新线程是登录窗口类,然后将其移交给调度器。但在新线程启动后,主线程继续以相同的方式在仪表板窗口上开始工作,结果是,该进程的某些部分无法与另一个线程同时运行。不知道为什么,但我就是这样解决的。

所以基本上启动ui的代码现在看起来像这个

private AutoResetEvent _dashboardStartWaitEvent = new AutoResetEvent(false);   
internal void SetupAndRunDashboard()
{
    if (DashboardUiThread == null)
    {
        DashboardUiThread = new Thread(RunDashboard) { Name = "dashboardUIThread" };
        DashboardUiThread.SetApartmentState(ApartmentState.STA);
        DashboardUiThread.Start();
        _dashboardStartWaitEvent.Wait();
    }
}
private void RunDashboard()
{
    UIDashBoard = new Dashboard(this);
    _dashboardStartWaitEvent.Set();
    Dispatcher.Run();
}

因此,主线程在继续之前等待ui的初始化,因此ui的初始化一次一个,没有重叠,这解决了问题。