简体   繁体   English

创建窗口xaml时为nullreferenceexception

[英]nullreferenceexception while creating window xaml

I have an issue in my WPF application, which essentially has 2 windows, a login window and a dashboard window and I get null reference exceptions intermittently when I load these windows. 我的WPF应用程序存在一个问题,该应用程序本质上具有2个窗口,一个登录窗口和一个仪表板窗口,并且在加载这些窗口时会间歇性地得到null引用异常。 A typical exception looks like this (dashbaord) 一个典型的异常看起来像这样(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()

Which is an obscure error. 这是一个晦涩的错误。 deep in the loadcomponent class. 在loadcomponent类中。

I start my dashboard using 2 methods in my main AppContext Class as follows 我在主AppContext类中使用2种方法启动仪表板,如下所示

    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();
    }

and my dashboard constructor looks like this 我的仪表板构造函数如下所示

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

I would really appreciate help on this as I am well and truly stumped since it is deep in the windows API that the null ref is being thrown. 我非常感谢您的帮助,因为我很好,也确实很沮丧,因为在Windows API的深处抛出了空引用。

OK, so I found out what is happening, albeit on quite a high level, but it seems I can't start 2 ui's concurrently. 好的,所以我知道发生了什么,尽管水平很高,但是看来我无法同时启动2 ui。 As I stated in my question, I run the login ui and dashboard ui, and I start them in the way described above, that is start a thread with STA Apartment state, the new thread then new's the login window class and hands it over to the dispatcher. 如我在问题中所述,我运行登录ui和仪表板ui,并按上述方式启动它们,即以STA Apartment状态启动线程,新线程然后是登录窗口类,并将其移交给调度员。 But after the new thread is started the main thread goes ahead and starts its work on the dashboard window in the same fashion and as it turns out, some part of that process cannot run concurrently with another thread. 但是在启动新线程之后,主线程继续前进,并以相同的方式在仪表板窗口上开始工作,事实证明,该过程的某些部分无法与另一个线程同时运行。 Not sure why, but thats how I resolved it. 不知道为什么,但这就是我解决的方式。

So basically the code for starting the ui's now look like this 因此,基本上,用于启动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();
}

So the main thread waits for the ui to be initialised before it carries on, hence the ui's are initialised one at a time without overlapping and this resolved the issue. 因此,主线程在进行ui之前会等待ui初始化,因此一次将ui初始化为ui不会重叠,这解决了问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM