Form.show(), начиная с события в другом потоке

#c# #multithreading #events #invoke

#c# #многопоточность #Мероприятия #вызвать

Вопрос:

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

 namespace test
{
    public partial class Form1 : Form
    {
        Class1 cl1 = new Class1();
        static public Form2 f2 = new Form2();
        public Form1()
        {
            InitializeComponent();

            cl1.event1  = new Class1.del(CreateForm);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            cl1.Almog();
        }

        static public void CreateForm()
        {
            //Form2 f2 = new Form2();
                f2.Show();
        }
    }
} 

namespace ClassLibrary1
{
    public class Class1
    {
        public event del event1;
        public delegate void del();

        public void Almog ()
        {
            Thread t1 = new Thread(Print);
            t1.Name="class1";
            t1.Start();
        }
        public void Print ()
        {
            event1();
            while(true)
            {
                Console.WriteLine("in the loop");
            }
        }

    }

}
  

Ответ №1:

Вам нужно вызвать форму с помощью MethodInvoker . вот так…

            static public void CreateForm()
            {
              Form2 f2 = new Form2();
              f2.Invoke(new MethodInvoker(delegate()
              {

                    f2.Show();
              }));
            }
  

Комментарии:

1. Это не будет компилироваться. Использование this в статическом методе невозможно.

Ответ №2:

Вы получите недопустимую операцию межпоточного исключения, если вы вызываете одну форму из другой. Для этого вам нужно вызвать вызов метода.

 static public void CreateForm()
{
   f2.Invoke(new MethodInvoker(delegate(){ f2.Show();}));
}
  

Кроме того, прочитайте это для дальнейшего разъяснения:

Как: Сделать потокобезопасные вызовы элементов управления Windows Forms

Ответ №3:

Вам нужно проверить, нужно ли вызывать вызов метода.

 static public void CreateForm() {
    Action action = () => { f2.Show(); };
    if (f2.InvokeRequired) {
        f2.Invoke(action);
    } else {
        action();
    }
}