简体   繁体   English

在新线程中启动表单并在它们之间引发事件

[英]Start form in new thread and Raise events between them

I try to start a form in an new thread (see code schema below). 我尝试在新线程中启动表单(请参见下面的代码架构)。 But the form Closes after it shows up. 但是,窗体显示后将关闭。

Thread te;    
dia di = new dia();
private static Thread te;
public static event AddingNewEventHandler tempchange;
public delegate void AddingNewEventHandler(int sender, EventArgs e);
static void Main(string[] args)
{    
   di.Coneig += new Config.AddingNewEventHandler(config);
   te = new Thread(new ThreadStart(di.Show));     
   te.Start();    
   while(true)
   {
     //async code to Form
   }
}

public static void config(int[] sender, EventArgs e)
{
    //Edit some values in the main(Class variables)
}
Thread te;    
dia di = new dia();

static void Main(string[] args)
{    
   te = new Thread(new ThreadStart(di.Show));     
   te.Start();    
   Console.ReadKey();
}

EDIT: 编辑:

This one works i checked.. 我检查过这个作品。

    static void Main(string[] args)
    {
       Form di = new Form();


        Thread te = new Thread(() => 
        {
            Application.EnableVisualStyles();
            Application.Run(di);
        });
        te.Start();
    }

Try this: 尝试这个:

te = new Thread(new ThreadStart(()=>di.ShowDialog()));

I'm not sure about the use for it, but it should work. 我不确定它的用途,但应该可以。

Thread will stay alive until you close the form. 线程将保持活动状态,直到您关闭表单。

You can use 您可以使用

te.Join();

as the last line before Main ends. 作为Main结束之前的最后一行。 This should make it work. 这应该使它工作。

Longer explanation to how it should be 关于它应该如何的更长的解释

When you start a windows form application, you start a GUI/Event/Main thread. 当您启动Windows窗体应用程序时,您将启动GUI /事件/主线程。 Visualize an infinite while loop like below somewhere in the winforms library 可视化一个无限的while循环,就像下面在winforms库中的某个地方

Queue<EventArgs> EventQueue = new Queue<EventArgs>();
while (!StopRequested) {
    if (EventQueue.Any())
        ProcessEvent(EventQueue.Dequeue());
    Thread.CurrentThread.Sleep(100);
}

All the controls are created in this thread and all the events are fired in this thread. 在该线程中创建所有控件,并在该线程中触发所有事件。 Now since this code does not exist in your code, the only way to get a GUI/Event related service is by posting into this EventQueue 现在,由于此代码不存在于您的代码中,因此获得GUI / Event相关服务的唯一方法是将其发布到此EventQueue

Now with this background, let's approach your situation. 现在有了这种背景,让我们来处理您的情况。

Raising and Handling Events 引发和处理事件

Raising and handling events work the exact same way with one form/thread as it works with multiple forms/threads. 引发和处理事件对一个表单/线程的工作方式完全相同,就像对多个表单/线程的工作方式一样。 Remember, raising events is simply the act of posting into that EventQueue and calling of event handlers happens from within the ProcessEvents 记住,引发事件只是将事件发布到该EventQueue ,而事件处理程序的调用是在ProcessEvents内部进行的

Form Life-Cycle 形成生命周期

In a typical WinForms application, you would use a line like below to tell the system to create an EventQueue and associate its life-cycle with the life-cycle of the form. 在典型的WinForms应用程序中,您将使用下面的一行来告诉系统创建EventQueue并将其生命周期与表单的生命周期相关联。

Application.Run(new Form());

You can use 您可以使用

new Form().Show()

to start pumping events into the EventQueue , consequently displaying the form, but remember that as soon as your application's main thread reaches the end of Main , the EventLoop will be abruptly terminated. 开始将事件泵入EventQueue ,从而显示表单,但是请记住,一旦您的应用程序的主线程到达Main的末尾, EventLoop就会突然终止。

So closing this form will cause your application to stop, and vice-versa. 因此,关闭此表单将导致您的应用程序停止,反之亦然。

Your case 你的情况

I would strongly advise you to launch the Form from the main thread and simply do the other work on a new thread. 我强烈建议您从主线程启动Form,然后在新线程上简单地完成其他工作。 I see that you are using sender as an int and an int[] , which is a problem. 我看到您将sender用作intint[] ,这是一个问题。 Below is how I would write if I need to achieve the same goal. 如果需要达到相同的目标,下面是我的写法。 I have tried to keep it similar to your sample whenever I could 只要有可能,我都会尽量使其与您的样本相似

class Program {
    static Form1 frm;

    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        frm = new Form1();
        frm.Test += TestEventHandler;

        new Thread(new ThreadStart(DoAsyncProcessing)).Start();

        Application.Run(frm);
    }

    static void DoAsyncProcessing() {
        // async code goes here
        Thread.Sleep(5000);

        // raise the event
        frm.RaiseTestEvent("Test Event Data");
    }

    static void TestEventHandler(object sender, TestEventArgs e) {
        System.Diagnostics.Debug.WriteLine("Received test event with data: " 
            + e.EventData);
    }
}

public partial class Form1 : Form {
    public event EventHandler<TestEventArgs> Test;

    public Form1() {
        InitializeComponent();
    }

    public void RaiseTestEvent(string eventData) {
        var arg = new TestEventArgs() { EventData = eventData };
        OnTest(arg);
    }

    protected virtual void OnTest(TestEventArgs e) {
        EventHandler<TestEventArgs> handler = Test;
        if (handler != null)
            handler(this, e);
    }
}

public class TestEventArgs : EventArgs {
    public object EventData { get; set; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM