0

I have 2 Forms, in Form1 , there are a lot of transaction to be done, so i have used the BackgroundWorker. so during the action to be taken i want the form2 to be opened and shows the progressbar ( the progress of the actions ) so I have done like this:

This is Form1

public partial class Form1 : Form
{
    Form2 form2 = new Form2();
    public Form1()
    {
        InitializeComponent();
        Shown += new EventHandler(Form1_Shown);

        // To report progress from the background worker we need to set this property
        backgroundWorker1.WorkerReportsProgress = true;
        // This event will be raised on the worker thread when the worker starts
        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
        // This event will be raised when we call ReportProgress
        backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
    }

    void Form1_Shown(object sender, EventArgs e)
    {
        form2.Show();
        // Start the background worker
        backgroundWorker1.RunWorkerAsync();

    }


    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        // Your background task goes here
        for (int i = 0; i <= 100; i++)
        {
            // Report progress to 'UI' thread
            backgroundWorker1.ReportProgress(i);
            // Simulate long task
            System.Threading.Thread.Sleep(100);
        }
        form2.Close();
    }


    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // The progress percentage is a property of e
        form2.progressBar1.Value = e.ProgressPercentage;
    }
}

I have a Progressbar in form2 which its modifier is public. the problem is that when the actions would be accompilshed the form2 ( which contans the progress bar) should be closed , So i used

    form2.Close();

but i get this error message

  Cross-thread operation not valid: Control 'Form2' accessed from a thread other than the thread it was created on

how can i solve this problem?

leppie
  • 115,091
  • 17
  • 196
  • 297
nnmmss
  • 2,850
  • 7
  • 39
  • 67
  • You will need to put `form2.Close()` into `backgroundWorker1.RunWorkerCompleted` event handler. – Kirill Shlenskiy Sep 23 '14 at 05:27
  • This question is answered on StackOverflow at least a few times a day. I have marked this at a duplicate of a single one - however, feel free to click through all of the related ones that are the same issue. – Simon Whitehead Sep 23 '14 at 05:32

2 Answers2

2

Use delegate to make it thread safe

 if(form2.InvokeRequired)
    {
        form2.Invoke(new MethodInvoker(delegate { form2.Close() }));
    }
Dark Knight
  • 3,507
  • 8
  • 35
  • 44
0

The problem is the control just can be accessed by the thread that create it.

Check this:

http://msdn.microsoft.com/en-us/library/ms171728.aspx

And this :

Cross-thread operation not valid: Control 'Form2' accessed from a thread other than the thread it was created on

Community
  • 1
  • 1
Ollie Strevel
  • 861
  • 1
  • 14
  • 27