Calculate time of processing a rule and use in progress-bar - c#

I have created a program that uploads a file in server using ftp. Now I want to use a progress bar when file uploading in server. Means when file is upload progress bar start with value=0 when upload doing his work value of progress bar increase and when upload done value be max and then return to default;
i have no problem with upload just i dont know how to use progress bar when i uploading a file in server.
please help me.
my program picture
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
backgroundWorker1.RunWorkerAsync();
Upload(#openFileDialog1.FileName);
}
else
{ }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 100; i++)
{
Thread.Sleep(2);
backgroundWorker1.ReportProgress(i);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
this.Text = e.ProgressPercentage.ToString();
}

Here is an example of a program I use that processes a dynamic amount of parts and reports the progress. Hope it helps!
Here is the end of my part processing method:
int Progress = Convert.ToInt16(((Convert.ToDecimal(intCounter) / Convert.ToDecimal(txtPartsList.Lines.Count()))) * 100);
bw.ReportProgress(intCounter);
and the code for my progress changed handle:
private void bwExecuteProcess_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int Progress = Convert.ToInt16(Math.Floor(((Convert.ToDecimal(e.ProgressPercentage) / Convert.ToDecimal(txtPartsList.Lines.Count()))) * 100));
lblTotal.Text = string.Format("Total Processed: {0} of {1}", e.ProgressPercentage, txtPartsList.Lines.Count());
lblReaderTime.Text = string.Format("Time Elapsed (sec): {0}", (swMainProcess.ElapsedMilliseconds / 1000));
pgsMain.Value = Progress;
lblPercentComplete.Text = string.Format("Percent Complete: {0}%", Progress);
ttpMain.SetToolTip(pgsMain, string.Format("{0}% Complete", Progress));
}

Related

Why WinForm Gets Stuck with BackgroundWorker?

hi guys i tried to copy some files with this Code everything is good and the app will copy files but in copy progress i cant move my app or do anything
i tried to use thread but its not works i also use backgroundWorker but still nothing the only control that doesnt get stuck is progressBar its works fine here is my code :
public Form1()
{
InitializeComponent();
backgroundWorker1.Dispose();
backgroundWorker1.DoWork += BackgroundWorker_DoWork;
backgroundWorker1.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
backgroundWorker1.ProgressChanged += BackgroundWorker_ProgressChanged;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker2.DoWork += BackgroundWorker2_DoWork;
backgroundWorker2.WorkerReportsProgress = true;
}
private void BackgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
File.Copy(sourcePath, targetPath);
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < fileSize; i++)
{
int p = (i + 1) * 100 / Convert.ToInt32(fileSize);
backgroundWorker1.ReportProgress(p);
}
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
lbProgress.Text = e.ProgressPercentage.ToString();
progressBar1.Value = e.ProgressPercentage;
}
private void btnTarget_Click(object sender, EventArgs e)
{
folderBrowser = new FolderBrowserDialog();
if (folderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
targetPath += folderBrowser.SelectedPath + #"\" + fileName;
lbTarget.Text = targetPath;
}
}
private void btnSource_Click(object sender, EventArgs e)
{
op = new OpenFileDialog();
if (op.ShowDialog() == DialogResult.OK)
{
sourcePath += op.FileName;
lbSource.Text = sourcePath;
fileInfo = new FileInfo(sourcePath);
fileSize = fileInfo.Length / 1024;
fileName = fileInfo.Name;
MessageBox.Show(string.Format("File size is: {0} KB", fileSize));
}
}
private void btnCopy_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
backgroundWorker2.RunWorkerAsync();
}
You're updating the progress bar faster than the UI can update, for every single byte of the file being copied in a tight loop. You're flooding the UI thread with pointless work.
Remove backgroundWorker1, it's not doing anything useful anyway. If you don't have a way to track the progress (which you don't with File.Copy), just use a progress bar without progress (set Style to Marquee).
For testing I created a simple winform application with a button, a label and a background worker and added the following corresponding events:
private void OnBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
var worker = (BackgroundWorker)sender;
for (int i = 0; i < 10; i++)
{
Thread.Sleep(500);
worker.ReportProgress(i * 10);
}
}
private void OnBackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
{
labelProgress.Text = e.ProgressPercentage.ToString();
}
private void OnBackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
labelProgress.Text = "Done";
}
private void OnButtonProgressClick(object sender, System.EventArgs e)
{
backgroundWorker.RunWorkerAsync();
}
Works as expected.
Could You try to update Your DoWork to this:
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
int mainProgress = 0;
for (int i = 0; i < fileSize; i++)
{
int calculatedProgress = (i + 1) * 100 / Convert.ToInt32(fileSize);
if(calculatedProgress > mainProgress)
{
mainProgress = calculatedProgress;
backgroundWorker1.ReportProgress(mainProgress);
}
}
}
maybe You are doing so many updates that simply Window Thread is all the time updating only progress and don't have a time to make anything else?

Updating progressbar through backgroundworker in method

My programm (in C# using Windows Forms) is reading and parsing large amounts of Data and I'm using a Backgroundworker which calls those global methods (reading and parsing). I'd like to keep the user updated on how long it's going to take, so the Backgroundworker is supposed to display what action its doing and has a progressbar that should fill for every individual action too.
Unfortunately, I can't get it to work, as the progressbar just doesn't update at all and just stays empty.
Here is what I have so far:
private void InitializeBackgroundWorker()
{
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}
private void buttonParse_Click(object sender, EventArgs e)
{
DescriptionLabel.Visible = true;
progressBar1.Visible = true;
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
Methods.ParsePerfusionData(backgroundWorker1); //Also tried using 'worker' here, but didnt work either
}
And in the method it looks like that:
public static void ParsePerfusionData(BackgroundWorker worker)
{
for (int i = 2; i < Globals.DataList.Count; i++)
{
worker.ReportProgress(i / amount * 100);
rest of the code etc.
}
}
Can I not use a backgroundworker in a global method like that? Thanks in advance!
When i < amount then i / amount * 100 = 0 * 100 = 0.
Simply use i * 100 / amount instead.
Also make sure backgroundWorker1.WorkerReportsProgress = true
You can only report progress between distinct operations. That means either:
using a very modern class that supports this level of reporting. Such a classs might not exist for your case.
reverse engineering parts of the code down to the loop you want to make reporting on. Usually the loop that itterates over files or the like.
GUI updates must be contained to RunWorkerCompelted and ProgressReport events. And depending on how often updates happen, ProgressReport may have to be kept to only updating a progress bar.
Here some old code I wrote with BackgroundWorker wich should get you started:
#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
if (!bgwPrim.IsBusy)
{
//Prepare ProgressBar and Textbox
int temp = (int)nudPrim.Value;
pgbPrim.Maximum = temp;
tbPrim.Text = "";
//Start processing
bgwPrim.RunWorkerAsync(temp);
}
}
private void btnPrimCancel_Click(object sender, EventArgs e)
{
if (bgwPrim.IsBusy)
{
bgwPrim.CancelAsync();
}
}
private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
int highestToCheck = (int)e.Argument;
//Get a reference to the BackgroundWorker running this code
//for Progress Updates and Cancelation checking
BackgroundWorker thisWorker = (BackgroundWorker)sender;
//Create the list that stores the results and is returned by DoWork
List<int> Primes = new List<int>();
//Check all uneven numbers between 1 and whatever the user choose as upper limit
for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
{
//Report progress
thisWorker.ReportProgress(PrimeCandidate);
bool isNoPrime = false;
//Check if the Cancelation was requested during the last loop
if (thisWorker.CancellationPending)
{
//Tell the Backgroundworker you are canceling and exit the for-loop
e.Cancel = true;
break;
}
//Determin if this is a Prime Number
for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
{
if (PrimeCandidate % j == 0)
isNoPrime = true;
}
if (!isNoPrime)
Primes.Add(PrimeCandidate);
}
//Tell the progress bar you are finished
thisWorker.ReportProgress(highestToCheck);
//Save Return Value
e.Result = Primes.ToArray();
}
private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pgbPrim.Value = e.ProgressPercentage;
}
private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pgbPrim.Value = pgbPrim.Maximum;
this.Refresh();
if (!e.Cancelled && e.Error == null)
{
//Show the Result
int[] Primes = (int[])e.Result;
StringBuilder sbOutput = new StringBuilder();
foreach (int Prim in Primes)
{
sbOutput.Append(Prim.ToString() + Environment.NewLine);
}
tbPrim.Text = sbOutput.ToString();
}
else
{
tbPrim.Text = "Operation canceled by user or Exception";
}
}
#endregion

How to fill datatable from database in background worker and show progress in c# winform?

I am trying to fill a DataTable from database in background worker, and i want to show a progress update form meanwhile.
I know i can use a loop to show the progress, but how can i show the progress as it progress to fill the table?
This is the code that i have used to show a progress bar in a new form:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i <= 10; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
worker.ReportProgress(i * 10);
System.Threading.Thread.Sleep(500);
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Pass the progress to AlertForm label and progressbar
alert.Message = "In progress, please wait... " + e.ProgressPercentage.ToString() + "%";
alert.ProgressValue = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
}
else if (e.Error != null)
{
}
else
{
}
// Close the AlertForm
alert.Close();
button1.Enabled = true;
}

The RunWorkerCompleted is triggered before the progressbar reaches 100% [duplicate]

This question already has answers here:
Disabling .NET progressbar animation when changing value?
(5 answers)
Closed 7 years ago.
I'm doing my first WinForms application featuring a background worker and progress bar. When I run my code it looks like the progress bar is delayed, because its animation -- approaching 100% -- is not completed when the code for the RunWorkerCompleted is executed. (A few hundred milliseconds the progress bar is filled.)
Is there a way to make things more synchronized?
From a user perspective I'm expecting the progress bar to reach 100% before other things start to happen.
componentList.Count, below, is usually 5-15, meaning the progress animation jumps roughly 10-20% each increment.
My code:
private void ExecuteButton_Click(object sender, EventArgs e)
{
ExecuteButton.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int filesRun = 0;
foreach(string file in componentList)
{
api.ExecuteInstructions(file);
int progress = ++filesRun * 100 / componentList.Count;
backgroundWorker1.ReportProgress(progress);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
ExecuteButton.Enabled = true;
}
My current workaround, giving the impression of simultaneousness:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int filesRun = 0;
foreach(string file in componentList)
{
api.ExecuteInstructions(file);
int progress = ++filesRun * 100 / componentList.Count;
if(progress == 100)
progress--;
backgroundWorker1.ReportProgress(progress);
}
Thread.Sleep(650); // cosmetic paus
backgroundWorker1.ReportProgress(100);
}
UPDATE:
Using the trick suggested in the question "Disabling .NET progressbar animation when changing value?" I managed to solve my problem by using the existing implementation and then adding the following logic:
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
if (e.ProgressPercentage == 100)
{
progressBar1.Value = 101;
progressBar1.Maximum = 100;
progressBar1.Value = 100;
}
}
Do a simple trick, instead of solving the UI thread synchronization problem.
Simply set progress bar to 100% in _RunWorkerCompleted.
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Value = 100;
Application.DoEvents();
ExecuteButton.Enabled = false;
}

Running a method in BackGroundWorker and Showing ProgressBar

What I want is when some method is doing some task UI keeps itself active and I want to show the progress of the work in a progress-bar.
I have a method, a BackGroundWorker and a Progressbar. I want to call the method when BackGroundWorker starts running and show the progress. The method contains a loop. So, it can report the progress.
So, what can be done?
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'dataSet1.TBLMARKET' table. You can move, or remove it, as needed.
myBGWorker.WorkerReportsProgress = true;
}
private void myBGWorker_DoWork(object sender, DoWorkEventArgs e)
{
parseFiles();
}
private void myBGWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
myProgressBar.Value = e.ProgressPercentage;
}
private void myBGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done");
}
private void parseButton_Click(object sender, EventArgs e)
{
myBGWorker.RunWorkerAsync();
}
public void parseFiles()
{
for()
{
//parsing
myBGWorker.ReportProgress(...);
}
}
But it's not working. The Progressbar is not updating. Only a small progress is showing after the MessageBox "Done".
Instead of using one ParseFiles method (which should depend on myBGWorker) use loop and method which parse one file. Report progress percentage in that loop:
private void parseButton_Click(object sender, EventArgs e)
{
parseButton.Enabled = false;
myBGWorker.RunWorkerAsync();
}
private void myBGWorker_DoWork(object sender, DoWorkEventArgs e)
{
for(int i = 0; i < filesCount; i++)
{
ParseSingleFile(); // pass filename here
int percentage = (i + 1) * 100 / filesCount;
myBGWorker.ReportProgress(percentage);
}
}
void myBGWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
myProgressBar.Value = e.ProgressPercentage;
}
void myBGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
parseButton.Enabled = true;
MessageBox.Show("Done");
}
To. soham.m17
using with sender argument
private void myBGWorker_DoWork(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker;
for(int i = 0; i < filesCount; i++)
{
ParseSingleFile(); // pass filename here
int percentage = (i + 1) * 100 / filesCount;
worker.ReportProgress(percentage); // use not myBGWorker but worker from sender
}
}
I am sorry about the question. Actually the code works fine. It was not showing the Progressbar as the argument in myBGWorker.ReportProgress() was fraction and not percentage. So, it was not showing it. Sorry for the inconvenience.
Moderator may delete this thread. Otherwise it can be a tutorial for others.

Categories