window.ShowDialog стек исключение потока причины исключения.WPF - PullRequest
0 голосов
/ 30 ноября 2011

Что является основными причинами для window.ShowDialog () stackOverflowException в WPF?Я получаю это исключение через 10-20 секунд, когда я звоню:

if(myWindow.ShowDialog() == true)
{
   //other stuff
}

Окно отображается и работает хорошо, но затем я получаю это исключение.

Ответы [ 2 ]

2 голосов
/ 30 ноября 2011

Общей причиной SOE, подобной этой, является наличие обработчика событий, код которого вызывает повторное возникновение того же самого события. Простой пример:

    private void textBox1_TextChanged(object sender, TextChangedEventArgs e) {
        textBox1.Text += "a";
    }

Введите букву, программе требуется около 5 секунд, чтобы не хватить места в стеке и бомбы. Основным оружием для точной диагностики того, какой именно обработчик событий вызывает эту проблему, является отладчик, посмотрите в окно Call Stack. Вы решаете это, используя небольшую вспомогательную переменную, которая указывает, что вы ожидаете, что событие будет запущено снова, поэтому вы можете его игнорировать. Как это:

    bool changingText;

    private void textBox1_TextChanged(object sender, TextChangedEventArgs e) {
        if (changingText) return;
        changingText = true;
        try {
            textBox1.Text += "a";
        }
        finally {
            changingText = false;
        }
    }

Try / finally не является строго необходимым, но целесообразно, если вы ожидаете, что ваша программа будет работать после исключения.

0 голосов
/ 13 октября 2015

Удивительно, но исключение переполнения стека может быть вызвано многократным вызовом 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 реализован внутри, я не могу сказать, что является более глубокой причиной этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...