窗口.ShowDialog stackoverflowexception原因.WPF

本文关键字:WPF 原因 stackoverflowexception ShowDialog 窗口 | 更新日期: 2023-09-27 18:16:17

WPF中window.ShowDialog() stackOverflowException的主要原因是什么?当我调用

时,在10-20秒后收到这个异常:
if(myWindow.ShowDialog() == true)
{
   //other stuff
}

窗口显示并工作良好,但随后我收到此异常。

窗口.ShowDialog stackoverflowexception原因.WPF

这样的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是内部实现的,我说不出更深层次的原因是什么