1

我有一个 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 中)

谢谢大家的帮助

4

6 回答 6

1

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

于 2011-06-10T13:56:16.833 回答
0

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

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

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

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

于 2011-06-09T20:55:46.943 回答
0

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

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

于 2011-06-10T05:09:10.550 回答
0

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

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

发布 NHibernate 异常,我可能会离开这个..

于 2011-06-09T19:49:19.393 回答
0

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

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

于 2011-06-09T19:43:50.207 回答
0

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

于 2011-06-09T19:50:11.903 回答