窗口.ShowDialog stackoverflowexception原因.WPF
本文关键字:WPF 原因 stackoverflowexception ShowDialog 窗口 | 更新日期: 2023-09-27 18:16:17
WPF中window.ShowDialog() stackOverflowException的主要原因是什么?当我调用
时,在10-20秒后收到这个异常:if(myWindow.ShowDialog() == true)
{
//other stuff
}
窗口显示并工作良好,但随后我收到此异常。
这样的SOE的一般原因是具有事件处理程序,其代码导致再次引发相同的事件。一个简单的例子是:
private void textBox1_TextChanged(object sender, TextChangedEventArgs e) {
textBox1.Text += "a";
}
输入一个字母,大约需要5秒程序就会耗尽堆栈空间并爆炸。准确诊断哪个事件处理程序导致此问题的主要武器是调试器,请查看"调用堆栈"窗口。您可以通过使用一个小的辅助变量来解决这个问题,该变量指示您希望再次触发事件,以便您可以忽略它。这样的:
bool changingText;
private void textBox1_TextChanged(object sender, TextChangedEventArgs e) {
if (changingText) return;
changingText = true;
try {
textBox1.Text += "a";
}
finally {
changingText = false;
}
}
try/finally并不是必须的,但是如果你希望程序在发生异常后继续运行,那么它是明智的。
令人惊讶的是,反复调用window会导致堆栈溢出异常。异步ShowDialog。
public MainWindow()
{
InitializeComponent();
TheCallDelegate = TheCall;
_timer = new DispatcherTimer();
_timer.Tick += _timer_Tick;
_timer.Start();
}
DispatcherTimer _timer = null;
void _timer_Tick(object sender, EventArgs e)
{
_timer.Dispatcher.BeginInvoke(TheCallDelegate);
}
Action TheCallDelegate;
void TheCall()
{
Window win = new Window();
win.ShowDialog();
}
正如你所看到的,这里没有实际的递归(或者不应该有),但是一旦异常发生,你可以看到调用堆栈确实是满的。不看窗口。ShowDialog是内部实现的,我说不出更深层次的原因是什么