Как прервать поток, вызванный ShowDialog - PullRequest
0 голосов
/ 24 августа 2018

Наличие приложения C # Windows Forms со вторичным потоком, который получает запросы от внешней системы на отображение или скрытие формы / диалога. Я понимаю, что вторичные потоки не имеют механизма цикла сообщений. Я понимаю, что ShowDialog имеет свой собственный цикл сообщений, поэтому вторичный поток может вызвать его, но вторичный поток затем блокируется, пока форма не закрывается, и, таким образом, не может отвечать на более поздние запросы, чтобы скрыть форму. Проблема в том, как заставить форму, отображаемую вторичным потоком, скрыть [или снова стать видимой]. Попытка вызова прерывания во вторичном потоке, но это не прерывает и не прерывает ShowDialog. Ничто не может прервать ShowDialog, кроме обратного вызова ShowDialog UI, который вызывает Close.

1 Ответ

0 голосов
/ 27 августа 2018

На самом деле обе формы совместно используют один и тот же цикл сообщений.

Каждый код, который обрабатывает графический интерфейс пользователя, должен выполняться в одном потоке (который обрабатывает часть графического интерфейса пользователя).Вам нужно запустить команды в этом потоке, используя BeginInvoke.

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

Вот код для главного окна:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    Thread t;
    Form2 f2;

    private void button1_Click(object sender, EventArgs e)
    {
        t = new Thread(ThreadMethod);
        t.Start();
        button1.Enabled = false;
    }

    private void ShowForm()
    {
        f2 = new Form2();
        f2.ShowDialog();
    }

    private void ThreadMethod()
    {
        for (; ; )
        {
            Thread.Sleep(3000);
            if(f2 == null)
            {
                BeginInvoke((Action)(() => { ShowForm(); }));
            }
            else
            {
                f2.CloseMe();
                f2 = null;
            }
        }
    }
}

А затем код для формы, используемой в качестве диалога:

using System;
using System.Windows.Forms;

namespace QuestionTesting
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        public void CloseMe()
        {
            BeginInvoke((Action)(() => { Close(); }));
        }
    }
}

Это просто простой код и адаптируйте его по своему усмотрению.Вместо одних строк вы можете создать делегат и использовать его в вызове BeginInvoke.

...