WPF - 发生异常时的对话重用问题

时间:2011-08-03 13:17:07

标签: .net wpf

我有一个WPF对话框,当我尝试在抛出异常后重新显示对话框时,我收到以下错误...

“窗口关闭后,无法设置可见性或调用Show,ShowDialog或WindowInteropHelper.EnsureHandle。”

我已经完成了一些有关问题的阅读,如果您尝试重新显示已关闭的对话框,通常会显示此消息,但我不会重复使用对话框...

Dialog dialog = new Dialog();
Exception exception = null;
IDisposable disposable = this.subject.Subscribe(
b =>
{
    dialog.DialogResult = b;
    dialog.Close();
},
ex =>
{
    dialog.Close();
    exception = new Exception("An unexpected error occured", ex);
});

bool? dialogResult = dialog.ShowDialog();
disposable.Dispose();
if (exception != null)
{
   throw exception;
}

我可以根据需要多次执行此代码,直到抛出异常,即上面的消息显示在show dialog上。代码在主UI线程上执行。

有没有人知道为什么抛出异常会阻止显示新对话框?

此致 杰森

3 个答案:

答案 0 :(得分:0)

你不应该自己调用Dispose(),这可能会导致部分处理对象出现很多问题。请改用using块。

抛出异常很可能导致仅部分处理对话框对象,从而导致错误。

Dialog是自定义类吗?我不承认它是WPF的一部分。如果是,请确保正确实施IDisposable(根据MSDN)。

答案 1 :(得分:0)

在不知道subject.Subscribe做什么的情况下,确实有点难以确定,但我认为这就是正在发生的事情。

当一切正常时,Subscribe方法不会立即返回,因此在您致电ShowDialog之后才会调用您的成功委托。

但是,在获得一个异常后,它似乎在Subscribe后立即调用失败委托。然后,当您拨打ShowDialog时,您Dialog的{​​{1}}已被调用,因此会抛出您正在谈论的异常。

如果您要执行以下操作,则可以看到相同的行为:

Close

同样,在不知道主题课程的详细信息的情况下,我无法真正提供解决您的特定问题的方法,但希望您可以从此处追踪您的问题。

答案 2 :(得分:-1)

感谢您的回复。我已经设法解决了这个问题,但我不能100%确定为什么这样才能解决问题。这是代码现在的样子......

Dialog dialog = new Dialog();
Exception exception = null;
this.subject = new Subject<bool>();
IDisposable disposable = this.subject
    .ObserveOnDispatcher()
    .Subscribe(
         b =>
         {
              dialog.DialogResult = b;
              dialog.Close();
         },
         ex =>
         {
              dialog.Close();
              exception = new Exception("An unexpected error occurred.", ex);
         });

 bool? dialogResult = dialog.ShowDialog();
 disposable.Dispose();
 if (exception != null)
 {
     throw exception;
 }

关键是使用ObserveOnDispatcher(),我想也许错误处理程序在后台线程上调用dialog.Close()导致奇怪的beahviour,但无论我是否使用ObserveOnDispatcher(),OnError处理程序仍然在主UI线程上被解雇,很奇怪!

每次调用OnError时,我还需要新建主题,订阅主题的任何内容都会立即触发OnError!另一种手动处理订阅的方法可能是在OnNext处理程序中调用subject.OnCompleted,但我认为调用dispose更清楚。