I'm setting up a background worker for the first time. It is mostly working as the code runs and my stop/cancel button is working. However, I am also trying to report progress to update a progress bar but I cannot get this to fire at all.
I start the code from a button click which runs this code:
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.RunWorkerAsync();//this invokes the DoWork event
My Do_Work method:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
int j = 0;// Count cumulative imported files
int countDupFiles = 0;// Count number of previously imported csv files
int countImportedFiles = 0;// Count imported files
foreach (string folderPath in csvDirList)
{
string[] csvFileNames = Directory.GetFiles(#folderPath, "*.csv");
frmImportCsvData.replaceAll(csvFileNames, folderPath + "\\", "");
for (int i = 0; i < csvFileNames.Length; i++, j++)
{
string csvFilePath = folderPath + "\\" + csvFileNames[i];
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
if (dataLayer.ImportCsvDataBkgrnd(this, csvFilePath, compIdValue, csvFileCount, i))//new method processes subdirectories if tick box selected
{
countImportedFiles = countImportedFiles + 1;
}
else
{
countDupFiles = countDupFiles + 1;
}
System.Threading.Thread.Sleep(500);
}
worker.ReportProgress(j);//tried using worker and backgroundWorker1 but neither works
backgroundWorker1.ReportProgress(j);
//string proj = j.ToString();
//MessageBox.Show(proj);//Displays incrementing j as expected when not commented out
}
}
if (countImportedFiles > 0)
MessageBox.Show(countImportedFiles + " files were imported.");
if (countDupFiles > 0)
MessageBox.Show(countDupFiles + " files were not imported. Matches all ready in Database.");
}
Trying to fire either of these ProgressChanged events:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
string tbProgress = (e.ProgressPercentage.ToString() + "%");
MessageBox.Show(tbProgress + "backgroundWorker1");
importProgressBar(e.ProgressPercentage);
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
string tbProgress = (e.ProgressPercentage.ToString() + "%");
MessageBox.Show(tbProgress + "worker");
importProgressBar(e.ProgressPercentage);
}
Finally, I want the ProgressChanged event to trigger this method to update my progress bar:
public void importProgressBar(int i)
{
progressTableLayoutPanel.Visible = true;//display progress bar
int percProgress = 100 * (i + 1) / csvFileCount;
if (percProgress <= 99)// Required to prevent values above 100 that crash the code
progressBar.Value = percProgress + 1;//hack that makes the progress bar update when progress value decreases
progressBar.Value = percProgress;
percProgressLabel.Text = percProgress.ToString();
progressTableLayoutPanel.Update();//Required to display all progress bar table contents
//Thread.Sleep(200);
if (percProgress >= 100)
{
Thread.Sleep(200);
progressTableLayoutPanel.Visible = false;
}
}
The cancel button code, which works, looks like this:
private void stopImportButton_Click(object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
}
The messageboxes in my ProgressChanged events never show up and my progress bar is never set to visible. Any ideas what the problem could be?
Check this example:
BackgroundWorker bgw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
label1.Text = "";
label2.Text = "";
}
private void button1_Click_1(object sender, EventArgs e)
{
if (bgw == null)
{
bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
}
bgw.WorkerReportsProgress = true;
bgw.WorkerSupportsCancellation = true;
bgw.RunWorkerAsync();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
int total = 57; //some number (this is your variable to change)!!
for (int i = 0; i <= total; i++) //some number (total)
{
System.Threading.Thread.Sleep(100);
int percents = (i * 100) / total;
bgw.ReportProgress(percents, i);
//2 arguments:
//1. procenteges (from 0 t0 100) - i do a calcumation
//2. some current value!
}
}
void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label1.Text = String.Format("Progress: {0} %", e.ProgressPercentage);
label2.Text = String.Format("Total items transfered: {0}", e.UserState);
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//do the code when bgv completes its work
}
}
Maybe this helps you with your problem...
And try to put the progress to visible just after you call the background.doWork in the button click event.
Related
I'm trying to create a countdown where the text displays, "GAME STARTS IN: " and using a for loop and Thread.Sleep a variable counts down from three. I started by using the designer to create the "game starts in:" part, but after the variable wouldn't show up I moved it to code. Now nothing shows up. This is what I have now in my timer method:
if (!countedDown)
DoCountdown();
Countdown.Hide();
And then in a DoCountdown method:
this.Countdown.BackColor = System.Drawing.Color.Transparent;
this.Countdown.ForeColor = System.Drawing.Color.White;
this.Countdown.Location = new System.Drawing.Point(360, 17);
this.Countdown.Name = "Countdown";
this.Countdown.Font = new System.Drawing.Font("Segoe UI", 12F,
System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point);
this.Countdown.Size = new System.Drawing.Size(185, 24);
this.Countdown.TabIndex = 6;
countedDown = true;
for (int i = 3; i > 0; i--)
{
Countdown.Text = "GAME STARTS IN: " + i;
System.Threading.Thread.Sleep(1000);
}
I put a breakpoint at System.Threading.Thread.Sleep(100) and everything seemed normal. Countdown.Text was equal to "GAME STARTS IN: 3". After trying to integrate the solutions the text doesn't show up. Here is some more context in my code:
This is from my start screen form
private void QuitGame(object sender, EventArgs e)
{
Application.Exit();
}
private void StartMultiplayerGame(object sender, EventArgs e)
{
GameScreen startGame = new GameScreen();
startGame.Show();
Hide();
}
Try something like below. A button is used to start the timer and set the initial values.
int count = 3;
private void button2_Click(object sender, EventArgs e) {
timer1.Interval = 1000;
count = 3;
label1.Text = "GAME STARTS IN: " + count;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e) {
count--;
if (count != 0) {
label1.Text = "GAME STARTS IN: " + count;
}
else {
timer1.Stop();
label1.Text = "GAME STARTED";
MessageBox.Show(" -> GO");
}
}
Edit per OP comments.
Try the code like this in the start screen form...
private void StartMultiplayerGame(object sender, EventArgs e) {
count = 3;
label1.Text = "GAME STARTS IN: " + count;
timer1.Start();
}
Then change the timer code to...
private void timer1_Tick(object sender, EventArgs e) {
count--;
if (count != 0) {
label1.Text = "GAME STARTS IN: " + count;;
}
else {
timer1.Stop();
label1.Text = "Game Started";
GameScreen startGame = new GameScreen();
startGame.Show();
this.Hide();
}
}
loop blocking the main thread to refresh UI so the required scenario can be archived by moving the loop to a separate method
void doCountDown()
{
for (int i = 10; i > 0; i--)
{
setCountDownText( "GAME STARTS IN: " + i);
System.Threading.Thread.Sleep(1000);
}
}
creating anew thread that start this method
new System.Threading.Thread(new System.Threading.ThreadStart(doCountDown)).Start();
and because of the need to update UI in another thread and to make it safe separate the setText in a separate method that update based on checking required to invoke property this will make it work in all cases
void setCountDownText(string txtValue)
{
if (Countdown.InvokeRequired)
{
Action safeWrite = delegate { setCountDownText(txtValue); };
Countdown.Invoke(safeWrite);
}
else
Countdown.Text = txtValue;
}
The "modern" way to do this is using async/await.
For example, launching the DoCountdown() from a button handler could look like this:
async void testBtn_Click(object sender, EventArgs e)
{
await DoCountdown();
}
async Task DoCountdown()
{
// <Initialisation of Countdown elided for brevity>
for (int i = 3; i > 0; i--)
{
Countdown.Text = "GAME STARTS IN: " + i;
await Task.Delay(1000);
}
}
However, whatever calls DoCountdown() will need to be declared as async, and so on up the call tree.
Note that the only acceptable place to have async void rather than async Task as a return type for an async method is where the method is an event handler such as the button handler in the example above.
private int FilesNamesCounter = 0;
private String FileName = "";
private List<string> myGifs = new List<string>();
private bool cancelop = false;
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgw = (BackgroundWorker)sender;
int Counter = 0;
int percentage = 0;
int total = allfiles.Count;
for (int i = 0; i < allfiles.Count; i++)
{
if (bgw.CancellationPending == true)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = Properties.Resources.Weather_Michmoret;
e.Cancel = true;
makeGif = false;
cancelop = true;
timer1.Stop();
break;
}
else
{
timer1.Start();
Counter += 1;
// calculating percentage and report it
percentage = Counter * 100 / total;
bgw.ReportProgress(percentage);
converttogif();
}
}
if (makeGif == true)
{
FilesNamesCounter += 1;
unfreez.MakeGIF(myGifs, outputfile + FilesNamesCounter + ".gif", 80, true);
}
bgw.ReportProgress(100);
e.Result = allfiles;
}
Convertion method:
private void converttogif()
{
DirectoryInfo dirinfo = new DirectoryInfo(selectedfilesdirectoryName);
FileInfo[] gifFileInfo = dirinfo.GetFiles("*.gif");
Image gifImage;
for (int i = 0; i < allfiles.Count; i++)
{
FileName = allfiles[i];
gifImage = Image.FromFile(gifFileInfo[i].FullName);
gifImage.Save(FileName, System.Drawing.Imaging.ImageFormat.Gif);
gifImage.Dispose();
myGifs.Add(FileName);
}
}
Progress Changed event:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
}
Completed event:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
button2.Enabled = false;
lblStatus.Text = "Task Cancelled.";
}
else if (!(e.Error == null))
{
lblStatus.Text = "Error while performing background operation.";
}
else
{
lblStatus.Text = "Task Completed...";
allfiles = (List<string>)e.Result;
timer1.Stop();
button1.Enabled = false;
progressBar1.BackColor = Color.FromArgb(0, 211, 040);
displaylastanimatedgif();
}
}
The problem is with the converttogif method in the DoWork event.
It will do loop in loop and will make each time the loop in the converttogif over and over again since i'm doing a loop over the images in the dowork already.
What i want to do is to report the progress in percentages of the convertion progress to the progressBar1. If i have in allfiles for example 285 files image to convert then convert them once and report on each file convert the progress in percentage to the progressBar so the whole convertion should be in the progressBar start from 0% to 100% or maybe it's logical to start from 1% to 100%.
But the idea to report and show the convertion progress.
UPDATE
This is what i tried now:
private int FilesNamesCounter = 0;
private String FileName = "";
private List<string> myGifs = new List<string>();
private bool cancelop = false;
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgw = (BackgroundWorker)sender;
converttogif(bgw);
bgw.ReportProgress(100);
e.Result = allfiles;
}
private void converttogif(BackgroundWorker bgw)
{
int Counter = 0;
int percentage = 0;
int total = allfiles.Count;
DirectoryInfo dirinfo = new DirectoryInfo(selectedfilesdirectoryName);
FileInfo[] gifFileInfo = dirinfo.GetFiles("*.gif");
Image gifImage;
for (int i = 0; i < allfiles.Count; i++)
{
FileName = allfiles[i];
gifImage = Image.FromFile(gifFileInfo[i].FullName);
gifImage.Save(FileName, System.Drawing.Imaging.ImageFormat.Gif);
gifImage.Dispose();
myGifs.Add(FileName);
Counter += 1;
// calculating percentage and report it
percentage = Counter * 100 / total;
bgw.ReportProgress(percentage);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
button2.Enabled = false;
lblStatus.Text = "Task Cancelled.";
}
else if (!(e.Error == null))
{
lblStatus.Text = "Error while performing background operation.";
}
else
{
if (makeGif == true)
{
FilesNamesCounter += 1;
unfreez.MakeGIF(myGifs, outputfile + FilesNamesCounter + ".gif", 80, true);
}
lblStatus.Text = "Task Completed...";
allfiles = (List<string>)e.Result;
timer1.Stop();
button1.Enabled = false;
progressBar1.BackColor = Color.FromArgb(0, 211, 040);
displaylastanimatedgif();
}
}
The problem now is that it's getting to 99% and much before the end of the progressBar like 3/4 of the way but show 99% then it's waiting i used a breakpoint and it's getting to the completed event creating the animated gif then show 100% and the progressBar getting to the end.
How can i fix it ?
Easy, but not nice, way: pass the background worker to your converttogif function, and call bgw.ReportProgress(percentage); within the cicle.
A better solution is having your converttoGif be a part of a different class, raising its own "progress" event you can register to, and in the event handler call the bgw.ReportProgress
This would keep the gifconversion code isolated from the form and its backgroudworker, leaving the form the need to register for conversion class events.
Ok, I am having an issue with how to create and manage threads. Below is some sample code, with the method call that is slowing everything down commented (sendMail).
Part of the problem is, I need to keep the user alerted to the progress of the send mail. Running this on the UI thread has been making it where the form doesn't repaint after each message is sent. Not to mention I believe threading will actually speed up this program by a large amount.
private void btn_send_Click(object sender, EventArgs e)
{
// Stop user from clicking send multiple times
btn_send.Enabled = false;
// Reset Progress Bar
progressBar1.Value = 0;
// Get User List
List<string[]> mycsv = csvRead();
//Get info for progress bar
int total = mycsv.Count;
// Send Message to each user
for (int x = 0; x < total; x++)
{
// Visual Diplay, but not updating
txt_percent.Text = "Sending Message " +
x.ToString() + " of " + total.ToString();
//Actual send message
//This can take up to 10 seconds PER user
sendMail(mycsv[x][0], mycsv[x][1]);
// Update Progress Bar
progressBar1.Value = (int)Math.Round(((float)x / (float)total) * 100);
}
// Alert user to completion
txt_percent.Text = "Finished";
//Allow them to send again (hopefully with new message ;)
btn_send.Enabled = true;
}
How can I convert this to use threading, and keep using a progress bar?
Here is a rough implementation with a background worker. Feel free to tweak as needed:
BackgroundWorker bg = new BackgroundWorker();
private void button1_Click(object sender, EventArgs e)
{
if (bg.IsBusy) return;
progressBar1.Value = 0;
bg.DoWork += bg_DoWork;
bg.ProgressChanged += bg_ProgressChanged;
bg.RunWorkerCompleted += bg_RunWorkerCompleted;
bg.WorkerReportsProgress = true;
bg.RunWorkerAsync();
}
void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Alert user to completion
txt_percent.Text = "Finished";
}
void bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Visual Diplay, but not updating
txt_percent.Text = e.UserState.ToString();
progressBar1.Value = e.ProgressPercentage;
}
void bg_DoWork(object sender, DoWorkEventArgs e)
{
//Get info for progress bar
int total = 25;
// Send Message to each user
for (int x = 0; x < total; x++)
{
//Actual send message
sendMail();
bg.ReportProgress((int)Math.Round(((float)x / (float)total) * 100), "Sending Message " + x.ToString() + " of " + total.ToString());
}
}
private void sendMail()
{
Thread.Sleep(5000);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int currentProgress=-1;
while (currentProgress<length)
{
currentProgress=Worker.progress;
backgroundWorker1.ReportProgress(currentProgress);
Thread.Sleep(500);
length = Worker.UrlList.Count;
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int ix = e.ProgressPercentage;
progressBar1.Value = ix;
lblText.Text =ix+" %";
}
I wrote a program to download page sources by reading a file have about 1000 URLs. so I used Tasks to download pages async. here Worker.progress is the currently executed URL amount. though the debuger hits the backgroundWorker1.ReportProgress(currentProgress); it never enter to the backgroundWorker1_ProgressChanged.
private void StartButton_Click(object sender, EventArgs e)
{
t.makeUrlList(inputFile);
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += backgroundWorker1_DoWork;
backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
backgroundWorker1.RunWorkerAsync();
t.RunTasks();
Application.Exit();
}
background worker initializes when start button clicks...
here is where my tasks are created....
public void RunTasks()
{
if (numOfTasks > UrlList.Count)
numOfTasks=UrlList.Count-1;
Task[] t = new Task[numOfTasks];
int j = 0;
while ( j < UrlList.Count-1)
{
for (int i = 0; (i < t.Count())&&(j<UrlList.Count-1); i++)
{
try
{
if (t[i].IsCompleted || t[i].IsCanceled || t[i].IsFaulted)
{
t[i] = Task.Run(() => FindWIN(j));
j++;
progress = j;
}
}
catch (NullReferenceException ex)
{
t[i] = Task.Run(() => FindWIN(j));
j++;
progress = j;
}
}
}
}
If you want to BackgroundWorker supports updating progress information, the value of WorkerReportsProgress should be set to true . If this property is true , the user code can call ReportProgress for initiating event ProgressChanged .
Background worker initialization:-
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork+=backgroundWorker1_DoWork;
backgroundWorker1.ProgressChanged+=backgroundWorker1_ProgressChanged;
backgroundWorker1.RunWorkerAsync();
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int currentProgress = -1;
decimal length=1000;
while (currentProgress < length)
{
currentProgress = Worker.progress;
backgroundWorker1.ReportProgress(currentProgress);
Thread.Sleep(500);
length = Worker.UrlList.Count;
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
int ix = e.ProgressPercentage;
progressBar1.Value = ix;
lblText.Text = ix + " %";
}
See the demo code below. This is mostly untested, and certainly isn't 'production standard', but it should give you a good start!
It uses a ConcurrentQueue to hold the list of URLs to be processed. This is threadsafe, and makes life a lot easier.
It has a configurable number of urls and tasks. It's best not to make 1000 tasks, but instead have a queue of work items, and a smaller pool of Tasks which 'pull items' off the queue until it's empty. This means you can performance test different numbers of Tasks and find the best value for your problem.
It uses Invoke when updating the progress bar - this avoids the cross-thread exception.
No BackgroundWorker - just TaskFactory and Task
public partial class Form1 : Form
{
private const int UrlCount = 1000;
private const int taskCount = 10;
private ConcurrentQueue<string> urlList;
private List<Task> taskList;
public Form1()
{
InitializeComponent();
}
private void ResetQueue()
{
// fake up a number of strings to process
urlList = new ConcurrentQueue<string>(Enumerable.Range(0, UrlCount)
.Select(i => "http://www." + Guid.NewGuid().ToString() + ".com"));
}
private void button1_Click(object sender, EventArgs e)
{
ResetQueue();
var taskFactory = new TaskFactory();
// start a bunch of tasks
taskList = Enumerable.Range(0, taskCount).Select(i => taskFactory.StartNew(() => ProcessUrl()))
.ToList();
}
void ProcessUrl()
{
string current;
// keep grabbing items till the queue is empty
while (urlList.TryDequeue(out current))
{
// run your code
FindWIN(current);
// invoke here to avoid cross thread issues
Invoke((Action)(() => UpdateProgress()));
}
}
void FindWIN(string url)
{
// your code here
// as a demo, sleep a sort-of-random time between 0 and 100 ms
Thread.Sleep(Math.Abs(url.GetHashCode()) % 100);
}
void UpdateProgress()
{
// work out what percentage of the queue is processed
progressBar1.Value = (int)(100 - ((double)urlList.Count * 100.0 / UrlCount));
}
}
You should set WorkerReportsProgress property of your worker to true on initialization stage.
I have created a C# windows application in that I inserted the progress bar.
When a button is clicked the progress bar should appear and then it should start the process for some 2 to 3 seconds and when the process bar is completed it should be hidden.
I have used this code to solve this but its not working.
While the Progress bar is running, the label box that should be like "Generating... 45%" and after completing the label box should be "Generated 100%..", but when I insert the label its showing some errors.
Here is the picture before clicking the Generate button..
On Processing I Should get like this..
On Final Process id should be like this and the progress bar should hidden..
ProgressBar1.Visible = true;
if (isProcessRunning)
{
MessageBox.Show("A process is already running.");
return;
}
Thread backgroundThread = new Thread(
new ThreadStart(() =>
{
isProcessRunning = true;
for (int n = 0; n < 100; n++)
{
Thread.Sleep(1);
progressBar1.BeginInvoke(new Action(() => progressBar1.Value = n));
}
MessageBox.Show("Generated!!!");
if (progressBar1.InvokeRequired)
progressBar1.BeginInvoke(new Action(() => progressBar1.Value = 0));
isProcessRunning = false;
}
));
// Start the background process thread
backgroundThread.Start();
I suggest you to use BackgroundWorker to show progress bar in C# winform .
Here is an example ,
public partial class Form1 : Form
{
BackgroundWorker bgw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
label1.Text = "";
label2.Text = "";
}
private void button1_Click_1(object sender, EventArgs e)
{
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
bgw.WorkerReportsProgress = true;
bgw.RunWorkerAsync();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
int total = 57; //some number (this is your variable to change)!!
for (int i = 0; i <= total; i++) //some number (total)
{
System.Threading.Thread.Sleep(100);
int percents = (i * 100) / total;
bgw.ReportProgress(percents, i);
//2 arguments:
//1. procenteges (from 0 t0 100) - i do a calcumation
//2. some current value!
}
}
void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label1.Text = String.Format("Progress: {0} %", e.ProgressPercentage);
label2.Text = String.Format("Total items transfered: {0}", e.UserState);
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//do the code when bgv completes its work
}
}
You can set your progress bar's visible to false in bgw_RunWorkerCompleted .
The following links will show how to use backgroundworker
DotNetPerls
MSDN Reference
CodeProject
Good Luck :)
This is the Code i am using backgroundWorker..
public partial class Form1 : Form
{
BackgroundWorker bgw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
label3.Text = "";
this.StartPosition = FormStartPosition.CenterScreen;
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btn_generate_Click(object sender, EventArgs e)
{
progressBar1.Visible = true;
bgw.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
bgw.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
bgw.WorkerReportsProgress = true;
bgw.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int total = 100; //some number (this is your variable to change)!!
for (int i = 0; i <= total; i++) //some number (total)
{
System.Threading.Thread.Sleep(10);
int percents = (i * 100) / 100;
bgw.ReportProgress(percents, i);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label3.Text = String.Format("Progress: {0} %", e.ProgressPercentage);
if (e.ProgressPercentage == 100)
{
label3.Text = String.Format("Generated.. {0} %", e.ProgressPercentage);
}
// label2.Text = String.Format("Total items transfered: {0}", e.UserState);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Visible = false;
}
}`
In this There is a problem in the below code when i click the button for first time the progress bar runs one time and if i clicked second time it runs for 2 times and so on.. other wise the code is perfectly working..
public partial class Form1 : Form {
BackgroundWorker bgw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
label3.Text = "";
this.StartPosition = FormStartPosition.CenterScreen;
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btn_generate_Click(object sender, EventArgs e)
{ new BackgroundWorker();
progressBar1.Visible = true;
bgw.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
bgw.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
bgw.WorkerReportsProgress = true;
bgw.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int total = 100; //some number (this is your variable to change)!!
for (int i = 0; i <= total; i++) //some number (total)
{
System.Threading.Thread.Sleep(10);
int percents = (i * 100) / 100;
bgw.ReportProgress(percents, i);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label3.Text = String.Format("Progress: {0} %", e.ProgressPercentage);
if (e.ProgressPercentage == 100)
{
label3.Text = String.Format("Generated.. {0} %", e.ProgressPercentage);
}
// label2.Text = String.Format("Total items transfered: {0}", e.UserState);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Visible = false;
}
}