Reputation: 125
I'm trying to implement a BackgroundWorker
for monitoring a FileSystemWatcher
service.
My code is divided as:
A Classes.cs wich contains all methods , variables and FileSystemWatcher
implementation. And the main Form1 , wich contains form data and calls for the buttons\etc. When i run my program all that happens is the cursor to change (this was already expected) - the action happens in the background (things get done) but no report is shown on my progress bar. I got the example from a website and adapted it to my code - is there anything wrong i'm doing ? I believe there's something involved with the fact the only thing i call is the filesystemwatcher - but i expected that it would report the progress based on the action running "on background".
Any help is appreciated. Thanks
My form1 code (the BackgroundWorker
part) and the FileSystemWatcher
follows:
namespace PPF_Converter_v10
{
public partial class Form1 : Form
{
private FileManipulation prg;
//private FileManipulation FileOp;
public Form1()
{
InitializeComponent();
//FileOp = new FileManipulation();
prg = new FileManipulation();
//Load config before the program begins - loading sample config or newly generated config
prg.LoadConfig();
FillTextBox();
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
}
BackgroundWorker CODE:
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (!textBox1.Text.Contains("\\"))
{
MessageBox.Show("Please define the input folder before starting");
}
else if (!textBox2.Text.Contains("\\"))
{
MessageBox.Show("Please define the XML Output folder before starting");
}
else if (!textBox3.Text.Contains("\\"))
{
MessageBox.Show("Please define the Converted PPF Output Folder before starting");
}
else if (!textBox4.Text.Contains("\\"))
{
MessageBox.Show("Please define the Invalid PPF Output Folder before starting");
}
else
{
// calls the watcher
// prg.FileWatcher.SynchronizingObject = progressBar1.
prg.ProgramProcessing(textBox1.Text);
}
// do some long-winded process here
// this is executed in a separate thread
int maxOps = 1000000;
for (int i = 0; i < maxOps; i++)
{
//rtbText.AppendText(i.ToString() + "\r\n");
// report progress as a percentage complete
bgWorker.WorkerReportsProgress = true;
bgWorker.ReportProgress(100 * i / maxOps);
}
}
private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// update the progress bar
pbProgress.Value = e.ProgressPercentage;
}
private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// return to "normal" mode of operation
this.Cursor = Cursors.Default;
btnGo.Enabled = true;
}
private void btnGo_Click_1(object sender, EventArgs e)
{
// give the appearance of something happening
this.Cursor = Cursors.WaitCursor;
btnGo.Enabled = false;
// call RunWorkerAsync to start the background thread
bgWorker.RunWorkerAsync();
}
Exception thrown when the RichtextBox
is enabled:
Additional information: Cross-thread operation not valid: Control 'rtbText' accessed from a thread other than the thread it was created on.
Upvotes: 0
Views: 958
Reputation: 3222
You're invoking a MessageBox from the background thread on the foreground thread. That is like doing UI in two separate threads which is a no-no.
What you can do is either use events or an event aggregator from your background thread. I would probably go for the latter. This way, your background thread, when something is wrong, can (and should) abort immediately and notify through a message that it was unable to process the file.
Think of a background task as something that has no UI whatsoever. It is there in the background and can only communicate to the UI thread using events or messages.
Upvotes: 0