How can a new Form be run on a different thread in C#?

前端 未结 4 1053
野的像风
野的像风 2021-01-01 06:27

I\'m just trying to run a new thread each time a button click even occurs which should create a new form. I tried this in the button click event in the MainForm:



        
4条回答
  •  南笙
    南笙 (楼主)
    2021-01-01 06:54

    Although I'm not 100% aware of anything that says running completely seperate forms doing completely isolated operations in their own threads is dangerous in any way, running all UI operations on a single thread is generally regarded as good practice.

    You can support this simply by having your Subform class use BackgroundWorker. When the form is shown, kick off the BackgroundWorker so that it processes whatever you need it to.

    Then you can simply create new instances of your Subform on your GUI thread and show them. The form will show and start its operation on another thread.

    This way the UI will be running on the GUI thread, but the operations the forms are running will be running on ThreadPool threads.

    Update

    Here's an example of what your background worker handlers might look like - note that (as usual) this is just off the top of my head, but I think you can get your head around the basic principles.

    Add a BackgroundWorker to your form named worker. Hook it up to the following event handlers:

    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // Executed on GUI thread.
        if (e.Error != null)
        {
            // Background thread errored - report it in a messagebox.
            MessageBox.Show(e.Error.ToString());
            return;
        }
    
        // Worker succeeded.
    }
    
    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // Executed on GUI thread.
        progressBar1.Value = e.ProgressPercentage;
    }
    
    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        // Executed on ThreadPool thread.
        int max = (int)e.Argument;
    
        for (long i = 0; i < max; i++)
        {
            worker.ReportProgress(Convert.ToInt32(i));
        }
    }
    

    Your click handler would look something like:

    void button1_Click(object sender, EventArgs e)
    {
        int max;
    
        try
        {
            // This is what you have in your click handler,
            // Int32.TryParse is a much better alternative.
            max = Convert.ToInt32(textBox1.Text);
        }
        catch
        {
            MessageBox.Show("Enter numbers", "ERROR");
            return;
        }
    
        progressBar1.Maximum = max;
    
        worker.RunWorkerAsync(max);
    }
    

    I hope that helps.

提交回复
热议问题