I use progressbar in my form. I add "Application.DoEvents()" so that the progress bar fires when I click the button. However, in this case, I get the "index out of range" error. What do you think about how we can fix the error?
System.Threading.Thread.Sleep(10);
this.backgroundWorker1.RunWorkerAsync();
backgroundWorker1.WorkerReportsProgress = true;
Cursor.Current = Cursors.WaitCursor;
progressBar1.Show();
label1.Show();
pictureBox1.Show();
progressBar1.Value = 0;
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
Application.DoEvents();
progressBar1.PerformStep();
var val0 = dataGridView1.Rows[i].Cells[0].Value.ToString();
var val1 = dataGridView1.Rows[i].Cells[1].Value.ToString();
var val2 = dataGridView1.Rows[i].Cells[2].Value.ToString();
var val3 = dataGridView1.Rows[i].Cells[3].Value.ToString();
var val4 = dataGridView1.Rows[i].Cells[4].Value.ToString(); /
var val5 = Convert.ToDateTime(dataGridView1.Rows[i].Cells[5].Value.ToString());
var val6 = dataGridView1.Rows[i].Cells[6].Value.ToString();
var val7 = dataGridView1.Rows[i].Cells[7].Value.ToString();
var val8 = dataGridView1.Rows[i].Cells[8].Value.ToString();
Mehmet FatihPosted Sep 18, 2023, 12:34 PM
Thanks Sam for your detailed infirmation. I have solved the problem with the following codes.
public void DoProcessing(IProgress progress)
{
for (int i = 0; i != 100; ++i)
{
Thread.Sleep(100); // CPU-bound work
if (progress != null)
progress.Report(i);
}
}
progressBar1.Value= 0; constructor captures our UI context,(percent =>
progressBar1.Visible = true;
label1.Visible = true;
// The Progress
// so the lambda will be run on the UI thread.
var progress = new Progress
{
progressBar1.Value = percent;
progressBar1.PerformStep();
label1.Text= String.Format("Yükleme yüzdesi: {0} %", percent);
});
// DoProcessing is run on the thread pool.
await Task.Run(() => DoProcessing(progress));
Sam HobbsPosted Sep 18, 2023, 4:25 AM
Also, note that async and await do not create tasks (also called threads). You need something like the BackgroundWorker class to create a task and the BackgroundWorker class was designed to work with Windows Forms.
Sam HobbsPosted Sep 18, 2023, 4:22 AM
I am unable to edit my first reply. The following is additional to it.
Do you have a handler of the DoWork event? You must have that. Prasad's sample shows one way to do that.
Update: I see that some Microsoft sample code uses DoEvents and I think that is a bad sample.
Sam HobbsPosted Sep 18, 2023, 4:13 AM
Experienced C# programmers do not use Application.DoEvents. DoEvents was created for unmanaged Visual Basic (VB.Net is called managed) because unmanaged VB was unable to process Windows events. C# programs can use Application.DoEvents because it is in .Net but it should not be used.
You are using the BackgroundWorker class. That is good for Windows Forms. There is no need touse async and await in Windows Forms, especially if it is for doing background processing such as this.
Here is a technical explanation for why it is a mistake to use Application.DoEvents in a BackgroundWorker handler as you are trying to do. In Windows a task cannot access a window it did not create. Microsoft says it is not supported, so it might work sometimes but Microsoft warns it is not guranteed to work. The BackgroundWorker class is designed to make it easy for porogrammers to create a separate task. Therefore you are trying to use Application.DoEvents for a window in a task that did not create the window.
One thing you probably need to do is to put the code that does:
After the other code. I assume you need to call RunWorkerAsync after you set WorkerReportsProgress to true and after the other stuff.
Mehmet FatihPosted Sep 17, 2023, 4:27 PM
I am sorry to tell that it is the same result.
Prasad RaveendranPosted Sep 17, 2023, 3:15 PM
try something like this and see.
My personal opinion:
In general, if you're starting a new project or updating an existing one, using async/await is recommended, as it offers a more modern and flexible way to handle asynchronous operations. It's especially useful when dealing with I/O-bound tasks, such as network requests or file I/O, as it doesn't block the UI thread.
However, if you're working on a legacy codebase that already uses BackgroundWorker or if you're dealing with specific requirements where the BackgroundWorker fits well, you can continue to use it.
Keep in mind that technology and best practices can evolve over time, so it's a good idea to check for updates and recommendations in the context of your specific development environment and framework.
Mehmet FatihPosted Sep 16, 2023, 10:15 PM
You are very kind Prasad. It is not important. Maybe I couldn't explain it enough. Yes, It is true. I want to make a percentage indicator as much as the selected data. I partially achieved this. However, when I do not place the code “Application.DoEvents()”, the progressbar percentage does not appear. When I put it in, it gives the error ” Index out of range”.
Prasad RaveendranPosted Sep 16, 2023, 3:59 PM
To be completely honest, I should have posed this question right from the start. I apologize for that. Could you please clarify your requirements? If I understand correctly, you're looking to implement a data grid within a Windows Application. This grid will have several columns, including one labeled "Progress %," along with a button. When you click on this button, it should initiate a calculation and then display the calculated percentage in the corresponding row. Is my understanding accurate?
Mehmet FatihPosted Sep 16, 2023, 1:30 PM
I checked all of them but I am getting the same error incimprehensibly. Is there another way of showing progressbar percentage when I click the button? Is there an alternative to the Application.DoEvents?
Prasad RaveendranPosted Sep 16, 2023, 12:58 PM
If you are getting an error stating that the column name isn't found even though the column name is present in your DataGridView, there are a few possible reasons and solutions to consider:
Typo in Column Name: Double-check that you are using the exact column name and that there are no typos or extra spaces. Column names are case-sensitive, so ensure it matches the case of the column name in your DataGridView.
Data Binding: If you are binding your DataGridView to a data source (e.g., a DataTable), make sure that the column name you are trying to access exists in the data source. If the DataGridView is auto-generating columns, their names might be different from what you expect.
Column Index: If you prefer to access columns by index, make sure that you are using the correct index. The index is zero-based, so the first column has an index of 0, the second column has an index of 1, and so on.
Data Population Timing: Ensure that you are trying to access the column after the DataGridView has been populated with data. If you attempt to access a column before data is loaded, it may not recognize the column name.
DataGridView Configuration: Verify that the DataGridView is configured correctly and that columns have been added to it. You can do this in design mode or programmatically in your code.
Debugging: Use debugging techniques to inspect the DataGridView at runtime. You can set breakpoints in your code and check the DataGridView's properties to ensure the column names are correctly set.
If you are still facing issues after checking these points, please provide more specific information about your code, such as how you are populating the DataGridView and how you are attempting to access the column, so that I can offer more targeted assistance.
Mehmet FatihPosted Sep 16, 2023, 12:54 PM
When I use columnname, I get the error "columname isn't found" even though the column name is present.
Prasad RaveendranPosted Sep 16, 2023, 12:26 PM
Please double check how many columns you have in your data grid and compare the column numbers which you are using inside the code.
I would suggest to use the column name instead of number as below.
please try this and post the code here , if you are facing the issue
Mehmet FatihPosted Sep 16, 2023, 12:21 PM
I am sorry Prasad but I am getting the same result with these codes.
Prasad RaveendranPosted Sep 16, 2023, 11:58 AM
The "index out of range" error is likely occurring because you are assuming that all cells in each row of dataGridView1 contain values, but some cells might be empty or null, which can cause a NullReferenceException when you try to access their .Value property or convert them to a specific type.
To fix this issue, you should first check if the cell's value is not null or empty before accessing it. Here's how you can modify your code to handle this:
In the code above, we use the null-conditional operator (?.) to safely access the cell's value, and the null coalescing operator (??) to provide a default empty string if the cell's value is null or empty. For the DateTime conversion, we use DateTime.TryParse to handle potential conversion errors. This way, your code should no longer throw an "index out of range" error, and it will gracefully handle empty or null cell values.