WPF. Работа MessageBox или проблема с потоками

162
30 января 2020, 15:10

Имеется приложение WPF, в котором мне нужно открыть порт. В случае, если порт открыть не удается - вывести сообщение об ошибке и после закрытия этого сообщения завершить приложение. Ошибка выводится через MessageBox и ловится try-catch.

По моему опыту, MessageBox блокирует приложение до клика на "ок", однако в данном случае этого не происходит, сообщение выводится, но код продолжает выполняться и, соответственно, крашится при выполнении кода после try-cath. Пробовал выполнять эти строки через диспетчер главному потоку - не помогает. MessageBox, расположенный после try-cath, приостанавливает приложение(но, понятное дело, мне это не подходит)

Код:

        try
        {
            port.Open();
        }
        catch
        {
            MessageBox.Show("Ошибка открытия порта. Возможно устройство не подключено.");
            System.Windows.Application.Current.Shutdown();                
        }  

UPD: Вариант кода с использованием диспетчера.

        try
        {
            port.Open();
        }
        catch
        {
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
            (ThreadStart)delegate ()
                {
                    MessageBox.Show("Ошибка открытия порта. Возможно устройство не подключено.");
                    System.Windows.Application.Current.Shutdown();
                }
            );
        }     

UPD: На случай, если каким то образом код выше исполняется не в главном потоке и этот поток не успевает отправить запрос главному - добавил Thread.Sleep(10000); между try-cath и строкой, выполнение которой приводит к крашу. Не помогло.

Answer 1

Исходя из комментариев, могу сказать одно, если вы хотите синхронно показать сообщение с ошибкой, а потом закрыть приложение, воспользуйтесь методом Invoke. Он будет выполнен синхронно в том же потоке откуда вы его вызовите.

Код который вы вызываете выполняется асинхронно, игнорируя возвращаемый результат.

Код для теста XAML:

<Grid>
    <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
        <CheckBox x:Name="Throw" VerticalAlignment="Center" Content="Throw?" Margin="10">
        </CheckBox>
        <Button x:Name="Button" Content="Check" VerticalAlignment="Center" Margin="10" />
    </StackPanel>
</Grid>

Код:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Button.Click += Button_Click;
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (Throw.IsChecked == null || !Throw.IsChecked.Value) return;
        try
        {
            throw new NotImplementedException();
        }
        catch
        {
            Dispatcher.Invoke(() =>
            {
                MessageBox.Show("Error");
                Environment.Exit(1);
            });
        }
    }
}
READ ALSO
отличие array_splice от array_slice

отличие array_splice от array_slice

Вот срабатывает как надо:

154
Работа с сессиями php

Работа с сессиями php

Есть список товаров в корхинеУ каждого товара есть счётчик количества

134
Экспорт БД на пк с помощью php скрипта

Экспорт БД на пк с помощью php скрипта

Необходимо сделать экспорт БД на пк, путем нажатия кнопки в личном кабинетеПробовал сделать так:

133
Проблема SQL добавление в базу данных

Проблема SQL добавление в базу данных

С помощью этого кода я пытаюсь создать запись на сайтеКогда я нажимаю на "создать запись" на сайте, то страница просто обновляется и ничего...

156