Несколько потоков пользовательского интерфейса - Winforms - PullRequest
5 голосов
/ 27 сентября 2011

Я хочу создать несколько потоков пользовательского интерфейса в моем приложении. Я смоделировал сценарий, как показано ниже. Я создаю новое окно / форму по нажатию кнопки в фоне теме

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

        private void button1_Click(object sender, EventArgs e)
        {
            var thread = new Thread(() =>
            {
                Form f = new Form();
                Application.Run(f);
            });

            // thread.IsBackground = true; -- Not required. See Solution below
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }
    }  
}

Обратите внимание, что - я делаю IsBackground = true, потому что когда пользователь закрывает основную форму, дочерние формы / окна также должны закрываться. Есть ли более чистый / изящный способ добиться того же?

РЕДАКТИРОВАТЬ - я хочу создать выделенные потоки пользовательского интерфейса для каждого окна. я буду 10 таких окон, отображающих данные в реальном времени параллельно.

Решение - Это нормально? (согласно msdn и комментариям Ганса ниже) установили состояние квартиры (см. код выше)

protected override void OnClosed(EventArgs e)
{
    Application.Exit();
}

Ответы [ 3 ]

4 голосов
/ 27 сентября 2011

Рождение сообщений с потоками рано или поздно вас только укусит.

Из MSDN:

Элементы управления в Windows Forms привязаны к определенному потоку и не являются потокобезопасными.Поэтому, если вы вызываете метод элемента управления из другого потока, вы должны использовать один из методов вызова элемента управления для перенаправления вызова в соответствующий поток

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

Использование метода расширения делает его чище: Автоматизация шаблона кода InvokeRequired

2 голосов
/ 27 сентября 2011

Я думаю, вам нужно будет установить состояние квартиры вашего потока в однопоточное, как указано здесь ApartmentState для манекенов и здесь Thread-safe Form.Show : t.SetApartmentState(ApartmentState.STA). Хотя я не знаю, возможно ли это в фоновом потоке.

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

0 голосов
/ 27 сентября 2011

Вы можете обработать событие MainForm.Closing и вызвать subForm.Close (перенаправляется в правый поток) для каждой вложенной формы.

Я не уверен, почему вы хотите формы в отдельных потоках, хотя. Разве вы не можете просто отображать субформы немодально в главном потоке?

...