C
Chris Saunders
I'm using System.ComponentModel.BackgroundWorker to do some drawing in my
application.
The thread seems to run fine but it runs twice and I can't see why.
I'm going to show my code with everything that I think is not relevant
removed.
Perhaps the drawBitmap function can be ignored, I just included it because
it is the
actual work the tread is performing. (It's just a test case.)
Can anyone help?
namespace Mandolin
{
public partial class MainForm : Form
{
public MainForm()
{
backgroundWorkerDraw.DoWork += new
DoWorkEventHandler(backgroundWorkerDraw_DoWork);
backgroundWorkerDraw.ProgressChanged += new
ProgressChangedEventHandler(backgroundWorkerDraw_ProgressChanged);
backgroundWorkerDraw.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(backgroundWorkerDraw_RunWorkerCompleted);
}
private void goToolStripMenuItem_Click(object sender, EventArgs e)
{
if (backgroundWorkerDraw.IsBusy == false)
{
backgroundWorkerDraw.RunWorkerAsync();
}
}
private void drawBitmap(BackgroundWorker worker, DoWorkEventArgs e)
{
if (worker.CancellationPending)
e.Cancel = true;
else
{
for (int r = startRow; r < bitmapHeight; r++)
{
if (worker.CancellationPending)
e.Cancel = true;
else
{
for (int c = 0; c < bitmapWidth; c++)
{
mutex.WaitOne();
bitmap.SetPixel(c, r, Color.FromArgb(r * c));
mutex.ReleaseMutex();
if (e.Cancel)
c = bitmapWidth;
}
}
worker.ReportProgress((int)(((double)r /
(double)bitmapHeight) * 100));
if (e.Cancel)
{
mutex.WaitOne();
if (pauseButtonPushed == true)
startRow = r;
if (stopButtonPushed == true)
startRow = 0;
r = bitmapHeight;
mutex.ReleaseMutex();
}
}
}
}
private void backgroundWorkerDraw_DoWork(object sender,
DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
drawBitmap(worker, e);
}
private void backgroundWorkerDraw_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
statusBar.Text = e.ProgressPercentage.ToString() + " percent
complete.";
Graphics g = CreateGraphics();
mutex.WaitOne();
g.DrawImage(bitmap, rect);
mutex.ReleaseMutex();
}
private void backgroundWorkerDraw_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
toolStripButtonPlay.Enabled = true;
toolStripButtonPause.Enabled = false;
toolStripButtonStop.Enabled = false;
goToolStripMenuItem.Enabled = true;
pauseToolStripMenuItem.Enabled = false;
stopToolStripMenuItem.Enabled = false;
statusBar.Text = statusBarReady;
}
}
}
Regards
Chris Saunders
application.
The thread seems to run fine but it runs twice and I can't see why.
I'm going to show my code with everything that I think is not relevant
removed.
Perhaps the drawBitmap function can be ignored, I just included it because
it is the
actual work the tread is performing. (It's just a test case.)
Can anyone help?
namespace Mandolin
{
public partial class MainForm : Form
{
public MainForm()
{
backgroundWorkerDraw.DoWork += new
DoWorkEventHandler(backgroundWorkerDraw_DoWork);
backgroundWorkerDraw.ProgressChanged += new
ProgressChangedEventHandler(backgroundWorkerDraw_ProgressChanged);
backgroundWorkerDraw.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(backgroundWorkerDraw_RunWorkerCompleted);
}
private void goToolStripMenuItem_Click(object sender, EventArgs e)
{
if (backgroundWorkerDraw.IsBusy == false)
{
backgroundWorkerDraw.RunWorkerAsync();
}
}
private void drawBitmap(BackgroundWorker worker, DoWorkEventArgs e)
{
if (worker.CancellationPending)
e.Cancel = true;
else
{
for (int r = startRow; r < bitmapHeight; r++)
{
if (worker.CancellationPending)
e.Cancel = true;
else
{
for (int c = 0; c < bitmapWidth; c++)
{
mutex.WaitOne();
bitmap.SetPixel(c, r, Color.FromArgb(r * c));
mutex.ReleaseMutex();
if (e.Cancel)
c = bitmapWidth;
}
}
worker.ReportProgress((int)(((double)r /
(double)bitmapHeight) * 100));
if (e.Cancel)
{
mutex.WaitOne();
if (pauseButtonPushed == true)
startRow = r;
if (stopButtonPushed == true)
startRow = 0;
r = bitmapHeight;
mutex.ReleaseMutex();
}
}
}
}
private void backgroundWorkerDraw_DoWork(object sender,
DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
drawBitmap(worker, e);
}
private void backgroundWorkerDraw_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
statusBar.Text = e.ProgressPercentage.ToString() + " percent
complete.";
Graphics g = CreateGraphics();
mutex.WaitOne();
g.DrawImage(bitmap, rect);
mutex.ReleaseMutex();
}
private void backgroundWorkerDraw_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
toolStripButtonPlay.Enabled = true;
toolStripButtonPause.Enabled = false;
toolStripButtonStop.Enabled = false;
goToolStripMenuItem.Enabled = true;
pauseToolStripMenuItem.Enabled = false;
stopToolStripMenuItem.Enabled = false;
statusBar.Text = statusBarReady;
}
}
}
Regards
Chris Saunders