简体   繁体   中英

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. 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. Visualize an infinite while loop like below somewhere in the winforms library

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

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

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.

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.

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. I see that you are using sender as an int and an int[] , which is a problem. 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; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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