Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closing a form that is created in another thread

I have been searching for an answer to my particular problem for a while with no success.

I have a task in my program that takes a few seconds and I want to show a new form while that task is being done. The new form has a loadingbar and some text.

I need to show the new form parallel to the task otherwise the task will not start untill I close the new form.

This is the solution I have now:

private void loadingBar()
{
    frmLoading frm = new frmLoading("Please wait while the database is being backed up", "This might take several days.");
    frm.ShowDialog();  

}

public void Backup()
{
    Thread load = new Thread(new ThreadStart(loadingBar));
    load.Start();

    ///Execute a task.

    load.Abort(); 
}

So, this works OK but my question is: Wouldn't it be better to close the the form "frm" in the load-thread to make it stop?

like image 849
Dave Avatar asked Aug 12 '13 13:08

Dave


3 Answers

You could do this a few ways...

1 - You could do as BendEg suggested and invoke you frmClose once you are ready

Something like;

Invoke(new Action(Close)); 

or

Invoke(new Action(() => frmMain.Close()));

2 - Or you could simply use a background worker;

The simplest way to demonstrate this would be to add a BackgroundWorker to your form, and use the events provided;

public Form1()
{
    InitializeComponent();
    backgroundWorker1.RunWorkerAsync();

    MessageBox.Show(@"Please wait while the database is being backed up", @"This might take several days.");
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    Debug.WriteLine("Running"); //Execute a task
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    Debug.WriteLine("Ended"); //Dispose of any objects you'd like (close yor form etc.)
}

I hope this helps.

like image 54
Hexie Avatar answered Sep 29 '22 12:09

Hexie


You can declare the form on Class-Level and later close it with an invoke. MSDN-Windows Forms Invoke

Like this:

    public class Class1
{
    private Form myForm;

    public Class1()
    {
        myForm = new Form();
    }

    public void DoSomeWork()
    {
        // ===================================================
        // Do Some Work...
        // ===================================================

        myForm.Invoke(new MethodInvoker(this.Hide));
    }

    public void Hide()
    {
        myForm.Hide();
    }

    public void Backup()
    {
        myForm.ShowDialog();

        Thread load = new Thread(new ThreadStart(DoSomeWork));
        load.Start();
    }
}
like image 45
BendEg Avatar answered Sep 29 '22 11:09

BendEg


I think this can work for you.

void YourMethod()
{
     WaitForm wf = new WaitForm();
     Invoke(new PleaseWaitDelegate(Launch),wf);
     bool val = BoolMethodDoWork();
     Invoke(new PleaseWaitDelegate(Close), wf);
                if(val)
                {
                    MessageBox.Show("Success!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                    return;
                }
                MessageBox.Show("Damn!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
delegate void PleaseWaitDelegate(Form form);
        void Launch(Form form)
        {
            new System.Threading.Thread(()=> form. ShowDialog()).Start();
        }

        void Close(Form form)
        {
            form.Close();
        }
like image 44
kitndirangu Avatar answered Sep 29 '22 11:09

kitndirangu