我有一个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台计算机上重现了这个bug(只需创建一个新的WPF应用程序并将此代码粘贴到App.xaml.cs中)
感谢大家的帮助
答案 0 :(得分:1)
我通过仅创建一次窗口(循环之前)来解决问题。我不是在finally块中关闭它而是调用Hide,而是在循环之后关闭它。
答案 1 :(得分:0)
可能会发生任意数量的异常,如果没有发布异常细节,则很难诊断。
如果我猜测,我的猜测就是那个视图.Close()正在抛出,因为你说它没有被抓住。
答案 2 :(得分:0)
尝试在catch语句中调用session.clear()。
Nhibernate将继续缓冲SQL,直到它写入数据库(flush)。如果遇到问题(异常),它不会在发生异常时将其抛出,而是在刷新会话时(当它尝试将SQL写入数据库时)。
发布NHibernate异常,我可能会离开这个......
答案 3 :(得分:0)
您只需要构建会话工厂和配置ONCE。它可以是一个全球对象。然后,每次循环,让会话工厂启动一个会话。因为你永远不会破坏会话工厂,所以构建另一个会破坏nhibernate,因为它只需要一个具有一个配置的会话工厂。
答案 4 :(得分:0)
使用您的代码我得到“System.InvalidOperationException:Application对象正在关闭。”从窗口 - 这似乎是正确的例外。 在资源加载完成实例化之前,窗口会从应用程序通知关闭。
解决您的问题的方法是等待创建窗口,直到您知道在Startup中没有出现异常。
您也可以更改您的finally部分以发送关闭,以便在关闭之前窗口初始化完成 - 我会尝试加载dispatcherpriority。
如果你在发布版本中运行,你将获得永无止境的循环。
答案 5 :(得分:0)
我不相信WPF运行时已准备好在OnStartup()方法中创建窗口。该方法通常用于初始化应用程序的上下文。初始窗口通常在App.xaml中的标记中指定为StartupUri。
尝试重构代码,让运行时使用StartupUri创建Window1()。