devexpress progress bar performstep method not showing - c#

i need to upload records from excel sheet to sql server
while uploading i need to show the progress in devexpress progress bar
and that too in a manner like uploading 1 out of 100 and it should increment until it finishes

Create a BackgroundWorker and report progress back to the main GUI Thread. Then update the progress bar value with the status coming from the BackgroundWorker.
Here is an example, it uses a common WinForms ProgressBar instead of a DevExpress ProgressBar but the principle is just the same.
public partial class Progress : Form
{
readonly BackgroundWorker _worker = new BackgroundWorker();
public Progress()
{
InitializeComponent();
_worker.WorkerReportsProgress = true;
_worker.DoWork += _worker_DoWork;
_worker.ProgressChanged += WorkerProgressChanged;
_worker.RunWorkerCompleted += WorkerRunWorkerCompleted;
_worker.RunWorkerAsync();
}
private void _worker_DoWork(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker;
// Simulate work (uploading Excel records to SQL Server)
for (var i = 1; i <= 100; i++)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
// Upload some data here, Sleep(100) is just an example
Thread.Sleep(100);
// Calculate current progress and report
worker.ReportProgress(i);
}
}
void WorkerProgressChanged(object sender, ProgressChangedEventArgs e)
{
_progressBar.Value = e.ProgressPercentage;
}
void WorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_progressBar.Value = 0;
}
}

Related

How to correctly implement BackgroundWorker to inform user that the task is progressing

The Problem
I have used the project from https://github.com/zaagan/BioMetrix and want to use BackgroundWorker to display a progression during long tasks (Ex: Get Log Data takes about 30 seconds)
What I've done so far
1- Added backgroundWorker1 from Toolbox
2- After InitializeComponent(), I've Added :
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
3- Added those functions:
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
{
System.Threading.Thread.Sleep(500);
worker.ReportProgress(i * 10);
}
}
}
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
this.Text = (e.ProgressPercentage.ToString() + "%");
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
this.Text = "Canceled!";
}
else if (e.Error != null)
{
this.Text = "Error: " + e.Error.Message;
}
else
{
this.Text = "Done!";
}
}
I was expecting to view the progression percentage on the main Caption title text while retrieving log data from the device.
You need to assign the event handler to the event
worker.DoWork += backgroundWorker_ProgressChanged;
If you have created a Windows Form you need to looking in events page of the Background Worker properties and find the DoWork event, then assign it a function to run.

how to report about method situation via progress bar wpf C#

i am working on project in C# and its contain a methods that need a long time to be executed so i need a progress bar that tell the user about how much remain and i don't know how .
i google for it and i see courses about BackgroundWorker and still don't know how to use it
private void Lock_Methods()
{
foreach (FolderInfo fi in FolderInfo)
{
// code need a lot of time ....
}
}
any help please ...
Declare
var bw = new BackgroundWorker()
{ WorkerReportsProgress = true };
bw.RunWorkerAsync();
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
And
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
for(int i = 0: i < FolderInfo.Count; i++)
{
//...
(sender as BackgroundWorker).ReportProgress((int)(100/FolderInfo.Count)*i, null);
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}

Can we call method in DoWork event?

I am exporting a Data Table to excel file using background worker. And I wanted to show the export progress using progress bar. Do we have to write the exporting code in Do Work event or can we call a method, which is present in other class.
In my code I tried calling different method. But its not working.
Below is the sample code.
public MainWindow()
{
InitializeComponent();
property = new Property();
this.DataContext = property;
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
System.Windows.Forms.MessageBox.Show(e.Error.Message);
}
else
{
System.Windows.Forms.MessageBox.Show("Exported Successfully");
}
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pbStatus.Value = e.ProgressPercentage;
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
Export export = new Export();
export.GenerateExcelFile();
}
You need to call worker.ReportProgress from worker_DoWork with a valid progress value
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
worker.ReportProgress(0);
// Some job
worker.ReportProgress(10);
// ...
// Finish
worker.ReportProgress(100);
}
I'm not sure how you are generating report. Further I'm supposing your pbStatus has Minimum="0" and Maximum="100". You can after exporting each row report progress something like that.
worker.ReportProgress(currentRow * 100.0 / totalRows);
You also set your progress bar intermediate if you are not sure how to calculate that by setting progress.IsIndeterminate to true
pbStatus.IsIndeterminate = true;

How can I loop through a DataGridView created on the main form in a BackgroundWorker?

I want to loop through a DataGridView that is created on the main form in a BackgroundWorker to export the data to a CSV file. The BackgroundWorker is created on a separate form where the progress of the export will be displayed via a progress bar. Here is the code on the export form that calls the BackgroundWorker:
private DataGridView exportGrid;
public void ExportCSV(DataGridView mainGrid)
{
this.exportGrid = mainGrid;
//Set progress bar maximum
progressBar1.Maximum = mainGrid.Rows.Count;
if (backgroundWorker1.IsBusy != true)
{
//Start the asynchronous operation
backgroundWorker1.RunWorkerAsync();
}
//Show the form
this.ShowDialog();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
//Write data rows
foreach (DataGridViewRow row in exportGrid.Rows)
{
//Check if the background worker has been cancelled
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
foreach (DataGridViewCell cell in row.Cells)
{
if (cell.Visible)
{
//Do CSV writing here...
}
}
//Report current progress to update UI
worker.ReportProgress(row.Index + 1);
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Update progress bar
this.progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Close the form once the background worker is complete
this.Close();
}
This code has been causing the following errors:
BindingSource cannot be its own data source. Do not set the
DataSource and DataMember properties to values that refer back to
BindingSource.
Cross-thread operation not valid: Control 'mainGrid' accessed from a
thread other than the thread it was created on.
I assume that these are because I am accessing the DataGridView in a thread that did not create it. What is the best way to go about doing this? Is it even possible?
Update:
The reason I am looping through the DataGridView instead of the datasource is that the users will be changing the column order, sort order and showing/hiding columns of the grid and they want these changes reflected in the exported data. Is there a different way to handle this?
Jeff in my opinion you are doing at minimum two mistakes in here:
Exporting data from a UI control instead of doing it from the data source;
Trying to access a UI control from a background thread;
I just would not try to access a UI control (Grid in your case) in a form which is not even the form where the background thread is declared, code will be so unclear and unreadable...
then consider that UI controls are used to render data in the UI; whenever you need to access the data for anything else than rendering in the screen you'd better access directly the datasource used to populate the UI.
I have ran into this before. Here's how I did this. This is taken straight out of the project I did this in. You should be able to get the idea of how to set up the threading to make this work. I didn't include the methods that actually write the CSV file, I'm assuming your main problem is with the threading. And as Davide Piras said, it's probably not a good idea to write the data directly from a control.
The BackGroundWorker's EventHandlers:
#region TableWorker Events
void TableWorker_DoWork(object sender, DoWorkEventArgs e)
{
bool done = false;
GetSwitch();
ProgressLabel.Visible = true;
while (!done)
{
for (int i = 1; i <= 100; i++)
{
Thread.Sleep(100);
TableWorker.ReportProgress(i);
}
done = Export.ExportDataTable(SaveFile, DataTable);
}
}
void TableWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Progress.Style = ProgressBarStyle.Blocks;
Progress.Value = e.ProgressPercentage;
ProgressLabel.Text = "Writing File: " + e.ProgressPercentage.ToString() + "% Complete";
}
void TableWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Progress.Value = 100;
ProgressLabel.Visible = false;
Progress.Visible = false;
//MessageBox.Show("Export Completed!");
TableWorker.Dispose();
ExportButton.Enabled = true;
this.Close();
}
#endregion
Event that starts the BackgroundWorker.
private void EntireTableButton_Click(object sender, EventArgs e)
{
dialogResult = Export.SetSaveDialog(SaveFile, ".csv", "csv file (*.csv)|*.csv");
if (dialogResult == DialogResult.OK)
{
TableWorker.RunWorkerAsync();
this.Hide();
ProgressLabel.Visible = true;
ProgressLabel.Text = "Retrieving Data...";
Progress.Style = ProgressBarStyle.Marquee;
Progress.Visible = true;
ExportButton.Enabled = false;
while (TableWorker.IsBusy)
{
Application.DoEvents();
}
Progress.Visible = false;
}
}
The Background worker's ReportProgress method will allow you to pass the progress to the ProgressChanged event. By doing this you can update the progress bar on another form.

c# windows form

I have a handler that returns some string messages. How can i put them into a form application? I mean I would like each time the handler is activated to print the result in a windows form. I now i need to use thread. I don't know how can i programatically create and add changes the name of the forms that pop up when a message is handled. Can someone please tell me how to do it?
I asssume that you have some work you want to do in the background and whenever an amount of progress is don you want to update the form...
Then I would use the backgroundworker:
BackgroundWorker bw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
}
private void bw_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.
System.Threading.Thread.Sleep(500);
worker.ReportProgress((i * 10)); //Activating the progressChanged event
}
}
}
Whenever you execute worker.ReportProgress() the event below will fire on the UI thread which is giving you the dynamic updates you wanted
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
}
When the worker is finished executing the RunWorkerCompleted event will fire
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
this.tbProgress.Text = "Canceled!";
}
else if (!(e.Error == null))
{
this.tbProgress.Text = ("Error: " + e.Error.Message);
}
else
{
this.tbProgress.Text = "Done!";
}
}
Source

Categories

Resources