I have a project encoded in .NET Winforms. I need to implement a data mining operation, print the text in a TextBox and update the progress.
I tried using BackgroundWorker, but it throws an InvalidOperationException ( Invalid cross-stream operation: Control 'xxxxx accessed from a stream other than the stream that was created on )
To narrow down the potential causes of the problem, I started a new project by including the following in it: Button - launch BackgroundWorker Shortcut - to print text. And the ProgressBar.
However, the result is the same. I searched in SOF and I was told to use a delegate, but I am not familiar with it.
This is an example of the code that causes the error:
using System; using System.Collections.Generic; using System.ComponentModel; namespace TestProject { public partial class Form1 : Form { private readonly BackgroundWorker _bw = new BackgroundWorker(); public Form1() { InitializeComponent(); _bw.DoWork += RosterWork; _bw.ProgressChanged += BwProgressChanged; _bw.RunWorkerCompleted += BwRunWorkerCompleted; _bw.WorkerReportsProgress = true; _bw.WorkerSupportsCancellation = false; } private void RosterWork(object sender, DoWorkEventArgs doWorkEventArgs) { for (int i = 0; i < 1000; i++) { label1.Text = i.ToString(); _bw.ReportProgress(Convert.ToInt32((i * (100 / 1000)))); } } private void BwProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; } private void btnStart_Click(object sender, EventArgs e) { progressBar1.Show(); _bw.RunWorkerAsync(); } private void BwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { progressBar1.Hide(); } } }
Update: I follow John Skeet's answer, he is really working on my test project, but is returning to my real project,
Layout of my form:
Form - TabControl - Tab1 -Tab1Panel -TextBox1
Upon reaching this line:
TextBox txtbox1 = new TextBox(); Tab1Panel.Controls.Add(txtbox1);
The error still occurs when I add a text box to the control panel programmatically.
Finally, I will replace with this:
if (Tab1Panel.InvokeRequired) Tab1Panel.Invoke((MethodInvoker)delegate { Tab1Panel.Controls.Add(txtbox1); }); else Tab1Panel.Controls.Add(txtbox1);
Everything works. How to detect an InvokeRequired control, is this control set?