Доступ к элементам управления WinForms не из основного потока

Если попробовать обратиться к элементам графического интерфейса не из основного потока, то возникнет исключение – InvalidOperationException.
Чтобы избежать этого, можно использовать метод – Invoke(Delegate). Метод выполняет указанный делегат в том потоке, которому принадлежит базовый дескриптор окна элемента управления.
Пример:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

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

        private void WithoutInvoke_Button(object sender, EventArgs e)
        {
            ThreadStart thStart = new ThreadStart(this.UpdateText_1);
            Thread th = new Thread(thStart);
            th.Start();
        }

        private void Invoke_Button(object sender, EventArgs e)
        {
            ThreadStart thStart = new ThreadStart(this.UpdateText_2);
            Thread th = new Thread(thStart);
            th.Start();
        }

        private void UpdateText_1()
        {
            this.label1.Text = "Text from UpdateText_1()";
        }

        private void UpdateText_2()
        {
            this.label1.Invoke(
                new MethodInvoker(
                    delegate
                    {
                        this.label1.Text = "Text from UpdateText_2()";
                    }
            ));
        }
    }
}
WinformsExternalCall1.png

В данном примере, если нажать на кнопку «Without Invoke» будет выброшено исключение – InvalidOperationException.
Результат:
WinformsExternalCall2.png

При нажатии на кнопку «Invoke» текст в label1 будет успешно изменен.
WinformsExternalCall3.png

Данный метод может пригодиться, например, при использовании таймера System.Windows.Forms.Timer, который запускается в отдельном потоке.
--
автор: Лисицын Антон

Last edited Jan 27, 2012 at 4:05 AM by basph, version 6

Comments

No comments yet.