1

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)
}
Neuxz
  • 311
  • 1
  • 4
  • 12
  • because the program finishes in main thread. you have to wait in main thread somehow. – M.kazem Akhgary Nov 27 '15 at 08:07
  • 5
    "i try to start a Form in an New Thread" - what for? – Dennis Nov 27 '15 at 08:09
  • read this answer: http://stackoverflow.com/a/428556/1506454, it may be helpful (questions are not duplicates though) – ASh Nov 27 '15 at 08:15
  • It's very unusual to run a form in a new thread - is there a special reason for this? You may find that if you clarify your reason, you'll get some good answers which will allow you to avoid this whole "form on a separate thread" business. – Simon MᶜKenzie Nov 27 '15 at 09:03
  • 1
    Possible duplicate of [Is it possible to use ShowDialog without blocking all forms?](http://stackoverflow.com/questions/428494/is-it-possible-to-use-showdialog-without-blocking-all-forms) – Uwe Keim Nov 27 '15 at 09:06

3 Answers3

4
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();
    }
Noxious Reptile
  • 838
  • 1
  • 7
  • 24
  • It should not stop the main because there is some other code which run async to the Form. – Neuxz Nov 27 '15 at 08:27
  • It works better but i have subscribed some events which are fired in the Main. The events can't reach the di form anymore. – Neuxz Nov 27 '15 at 08:57
  • @Benedikt You mean you need to fire event from window which should change the variables in main?? – Noxious Reptile Nov 27 '15 at 09:19
  • Correct. That's what the form is supposed to do. – Neuxz Nov 27 '15 at 09:25
  • @Benedikt Can you show me what kind of variables you need to change in main program? So that i can change in my program. I got the result in my custom program. – Noxious Reptile Nov 27 '15 at 10:04
  • The int[] which is given at the event Handler. – Neuxz Nov 27 '15 at 10:14
  • @Benedikt How do you wish to invoke?? I have a solution but still i did nt understand your requirement clearly. I have done a similar thing in my project but a bit different and i used it in WPF. – Noxious Reptile Nov 27 '15 at 10:22
  • I want to put the whole Class in the Thread so that the Event doesn't get lost. – Neuxz Nov 27 '15 at 10:43
1

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.

Fratyx
  • 5,717
  • 1
  • 12
  • 22
0

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; }
}
Vikhram
  • 4,294
  • 1
  • 20
  • 32