Reputation: 239
I have this DoWork event code:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgw = (BackgroundWorker)sender;
if (bgw.CancellationPending == true)
{
return;
}
else
{
Bitmap newbmp = new Bitmap(512, 512);
IEnumerable<Point> CommonList = null;
StreamWriter w = new StreamWriter(@"c:\diff\diff.txt");
pixelscoordinatesinrectangle = new List<Point>();
pixelscoordinatesinrectangle = pointsAffected.ToList();
DrawIt = false;
for (int i = 0; i < trackBar1FileInfo.Length; i++)
{
DrawIt = true;
trackBar1.Invoke(new MethodInvoker(delegate { trackBar1.Value = i; }));
timer1.Stop();
Button1Code();
timer1.Start();
trackBar2.Invoke(new MethodInvoker(delegate { trackBar2.Enabled = false; }));
trackBar1.Invoke(new MethodInvoker(delegate { trackBar1.Enabled = false; }));
trackBar1.Invoke(new MethodInvoker(delegate { LoadPictureAt(trackBar1.Value, sender); }));
pictureBox1.Load(trackBar1FileInfo[i].FullName);
trackBar1.Invoke(new MethodInvoker(delegate {
ConvertedBmp = ConvertTo24(trackBar1FileInfo[trackBar1.Value].FullName);
}));
ConvertedBmp.Save(ConvertedBmpDir + "\\ConvertedBmp.bmp");
mymem = ToStream(ConvertedBmp, ImageFormat.Bmp);
Button1Code();
pictureBox1.Invoke(new MethodInvoker(delegate { pictureBox1.Refresh(); }));
newpixelscoordinates = new List<Point>();
newpixelscoordinates = pointsAffected.ToList();
CommonList = pixelscoordinatesinrectangle.Intersect(newpixelscoordinates);
foreach (Point s in CommonList)
{
w.WriteLine("The following points are the same" + s);
newbmp.SetPixel(s.X, s.Y, Color.Red);
}
}
w.Close();
using (Graphics G = Graphics.FromImage(newbmp))
newbmp.Save(@"c:\newbmp\newbmp.bmp", ImageFormat.Bmp);
newbmp.Dispose();
}
}
The problem is when the backgroundworker dowork is working doing the job and then i close the form in the middle. Then it throw each time on a different line in the DoWork event exception say:
Cannot access a disposed object
For example on this line:
trackBar1.Invoke(new MethodInvoker(delegate { trackBar1.Value = i; }));
I tried in the FormClosing event to do:
backgroundWorker2.CancelAsync();
But it didn't do anything.
And i set in the designer backgroundworker2 WorkerSupportsCancellation to true already.
Inside the loop i tried for example to do that:
pictureBox1.Invoke(new MethodInvoker(delegate { pictureBox1.Refresh();
if (bgw.CancellationPending == true)
{
MessageBox.Show("cancelled");
}
}));
But nothing still i'm getting exception on this say: Cannot access a disposed object
Tried to add this bgw.CancellationPending check before the loop and in the top of the loop inside it. And inside every place in the loop i'm using the Begin Invoke
But still getting this exception all the time on a different line inside the loop.
In the form closing event i did:
private void ScanClouds_FormClosing(object sender, FormClosingEventArgs e)
{
backgroundWorker2.WorkerSupportsCancellation = true;
backgroundWorker2.CancelAsync();
}
And still when closing the form i'm getting the exception.
Upvotes: 0
Views: 349
Reputation: 2744
Note that setting this flag
bgw.CancellationPending = true
only notifies the worker thread that a cancel has been requested. The cancel will not actually happen until the thread in the DoWork checks this bgw.CancellationPending flag.
So you need to check in your loop
for (int i = 0; i < trackBar1FileInfo.Length; i++)
{
if(bgw.CancellationPending == false)
{
//...
}
}
Upvotes: 2
Reputation: 127563
You only check if bgw.CancellationPending == true
once in your DoWork code. You need to check that Every Single Time you come back from some operation that can "take a while", after each of your Invoke
calls for example (it might be a good idea to try to combine some of them into a single Invoke
and do more than one thing inside each call)
Upvotes: 1