簡體   English   中英

window.ShowDialog stackoverflowexception原因。 WPF

[英]window.ShowDialog stackoverflowexception reasons. WPF

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();
    }

正如您所看到的,這里沒有實際的遞歸(或者應該沒有)但是一旦發生異常,您就可以看到調用堆棧確實已滿。 沒有看看Window.ShowDialog是如何在內部實現的,我不能說這是什么原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM