【问题标题】:Weird unhandled exception with WPFWPF 奇怪的未处理异常
【发布时间】:2011-06-09 19:39:11
【问题描述】:

我有一个 WPF 应用程序,我通过它询问用户一些设置以连接到数据库,然后我连接到数据库(使用 NHibernate),如果一切正常,我将显示我的主视图。如果连接出现错误,我想告诉用户错误是什么,让他重试。这是一些简化的代码,可以满足我的要求:

编辑:

看来问题不仅仅在于 NHibernate。如果我只是在这里运行简单的应用程序,我会在构造函数中得到未处理的异常。

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        bool retry;

        do
        {
            retry = false;
            Window1 view = new Window1();

            try
            {
                throw new Exception("Test message");
                view.ShowDialog();
            }
            catch (Exception iException)
            {
                MessageBox.Show(iException.ToString());
                retry = true;
            }
            finally
            {
                view.Close();
            }
        }
        while (retry);
    }
}

我确实得到了未处理的异常,它给了我我的测试消息,所以它确实是我的异常(即使它在 try/catch 块内)。如果我在收到异常时中断,它会告诉我它发生在 Window1 的构造函数中。 Window1 不包含任何绑定或控件。如果您在 Visual Studio 2008 中创建新的 WPF 应用程序,它只是创建的基本 Window1。我已经在 2 台计算机上重现了这个错误(只需创建一个新的 WPF 应用程序并将此代码粘贴到 App.xaml.cs 中)

感谢大家的帮助

【问题讨论】:

  • 注意:我收到 MessageBox 两次,然后应用程序崩溃。我希望它只会在一个永无止境的循环中向我显示消息框。

标签: c# wpf window unhandled-exception


【解决方案1】:

我通过只创建一次窗口(在循环之前)解决了这个问题。我没有在 finally 块中关闭它,而是调用了 Hide,并且仅在循环之后才关闭它。

【讨论】:

    【解决方案2】:

    可能会发生任意数量的异常,如果不发布异常详细信息,则很难诊断。

    如果我猜测,我的猜测是 view.Close() 正在抛出,因为你说它没有被捕获。

    【讨论】:

    • 重点是配置需要改,不能保持同一个会话工厂。除非有办法更新工厂的设置?
    • 异常在构造函数内部的“view = new Views.MainView();”行处抛出。这就是为什么我不明白如何处理它。
    • 也不知道,但如果在 finally 块中可能出现 NullReferenceException,则在这种情况下不会捕获异常,因为视图从未初始化。
    【解决方案3】:

    尝试在你的 catch 语句中调用 session.clear()。

    Nhibernate 将继续缓冲 SQL,直到它写入数据库(刷新)。如果你有问题(异常),它不会在异常发生时抛出它,而是在会话被刷新时(当它试图将 SQL 写入数据库时​​)。

    发布 NHibernate 异常,我可能会在这个问题上走得更远..

    【讨论】:

    • 我刚刚编辑了我的帖子并添加了异常详细信息: -- WindowsBase.dll 中发生了“NHibernate.Cfg.HibernateConfigException”类型的未处理异常。附加信息:配置持久层时发生异常。 -- 我无法获得更多信息,我只能点击 Break 或 Continue (分别进入我的视图构造函数或终止应用程序。)
    • 我的问题不是异常本身,我知道这是因为我尝试使用不存在的文件配置配置。我的问题是这个异常不仅是configuration.Configure()抛出的,后面也是view构造函数抛出的,抓不到。
    • 而且我不能在我的 catch 语句中调用 session.Clear(),因为会话永远不会被创建(代码没有通过配置部分)。
    【解决方案4】:

    您只需要构建一个会话工厂和一次配置。它可以是一个全局对象。然后,每次通过循环,让会话工厂启动一个会话。由于您永远不会破坏会话工厂,因此构建另一个会话工厂会搞砸 nhibernate,因为它只需要一个具有一种配置的会话工厂。

    【讨论】:

    • 有没有办法在不创建新设置的情况下编辑工厂的设置(如连接字符串)?
    • 会话工厂永远不会被创建,代码没有通过行 configuration.Configure("bad stuff here");
    • 它不是在第一次通过时创建的吗?
    • 不,如果我在 ISession session = configuration.BuildSessionFactory().OpenSession();它永远不会在那里破裂。
    【解决方案5】:

    我不相信 WPF 运行时已准备好在 OnStartup() 方法期间创建窗口。该方法通常用于初始化应用程序的上下文。初始窗口一般在 App.xaml 的标签中指定为 StartupUri。

    尝试重构您的代码,让运行时使用 StartupUri 创建 Window1()。

    【讨论】:

    • no - 从 OnStartup 打开一个窗口是可以的,你没有一个 uri 为你的窗口 - 如果你只是从 window 派生并实例化你将没有任何 xaml 的 uri资源。
    • 我也相信从 OnStartup() 创建一个窗口是可以的,因为如果您使用 Microsoft 的 MVVM 工具包中的 MVVM 模板项目,它会从 OnStartup() 创建主窗口
    【解决方案6】:

    使用您的代码,我得到“System.InvalidOperationException:应用程序对象正在关闭”。从窗户看——这似乎是正确的例外。 窗口在其资源加载时完成实例化之前从应用程序收到关闭通知。

    解决您的问题的方法是等待创建窗口,直到您知道在 Startup 中没有遇到异常。

    您也可以更改您的 finally 部分以调度关闭,以便窗口初始化将在您关闭之前完成 - 我会尝试加载调度程序优先级。

    如果您在发布版本中运行,您将获得永无止境的循环。

    【讨论】:

    • 没有绝对没有约束力。 MainView 是一个空窗口,只包含一个空网格(没有数据或命令绑定,没有其他控件)
    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 2012-05-05
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    相关资源
    最近更新 更多