E
E
ElemAnybody2019-07-18 12:54:40
C++ / C#
ElemAnybody, 2019-07-18 12:54:40

C# (winform) how to put async and await in my code?

I have a code that just dies on its task (the interface stays up for 10 minutes) when processing +- 3500 rows of data. The idea came to mind to make the execution of this work asynchronous. The problem is that I didn't really understand how to use async in examples like mine!
c# code:

async void Button7Click(object sender, EventArgs e)
 {
 try
 {             
 textBox1.Text = "1";
 dataGridView2.SelectAll();
dataGridView2.ClearSelection();
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
 if (this.dataGridView2.CurrentRow != null)
{

dataGridView2.Rows.Add();
this.dataGridView2.Rows[i].Cells[0].Value = Convert.ToDouble((Convert.ToDouble(dataGridView1[2, i].Value) - Convert.ToDouble(dataGridView1[2, 0].Value)) * Convert.ToDouble(textBox1.Text));

this.dataGridView2.Rows[i].Cells[1].Value += string.Format("{0:0.#############}", Convert.ToDouble((Convert.ToDouble(dataGridView1[7, i].Value) - Convert.ToDouble(dataGridView1[7, 0].Value)) / 78));

this.dataGridView2.Rows[i].Cells[2].Value += string.Format("{0:0.########}", Convert.ToDouble((Convert.ToDouble(dataGridView1[12, i].Value) - Convert.ToDouble(dataGridView1[12, 0].Value)) / Convert.ToDouble((Convert.ToDouble(dataGridView1[15, 0].Value) - Convert.ToDouble(dataGridView1[12, 0].Value))))) + Environment.NewLine;

 this.dataGridView2.Rows[i].Cells[3].Value += string.Format("{0:0.###}", Convert.ToDouble((Convert.ToDouble(dataGridView1[31, i].Value) / 3) + Convert.ToDouble((Convert.ToDouble(dataGridView1[15, i].Value) - Convert.ToDouble(dataGridView1[12, i].Value))))) + Environment.NewLine;

this.dataGridView2.Rows[i].Cells[4].Value = Convert.ToDouble((Convert.ToDouble(dataGridView1[31, i].Value) / 2)) + Environment.NewLine;

this.dataGridView2.Rows[i].Cells[5].Value += string.Format("{0:0.#####}", Convert.ToDouble((Convert.ToDouble(dataGridView1[31, i].Value) / 3) + Convert.ToDouble((Convert.ToDouble(dataGridView1[15, i].Value) - Convert.ToDouble(dataGridView1[12, i].Value)) * 3))) + Environment.NewLine; 
}
else
 {
i--;
dataGridView2.Rows.RemoveAt(i);
GC.Collect();
GC.WaitForPendingFinalizers();
return;
}
}
 }
catch (Exception e2)
{
//Обрабатываете Exception - пишите в лог или выводите e.Message на панель
MessageBox.Show(e2.Message);
}
}

Datagridview1 stores the numbers (double) that are used in the calculations
In datagridview2, the answers that were used in the calculations
spoiler
It would be ideal if someone helped me with this code + correctly set collect and other details that clean up the garbage, because after such a calculation, I have almost 1000mb cache on my PC

But if there is some other way to speed up this process, then write.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
#
#, 2019-07-18
@mindtester

1 - advice - do not pull the garbage collector on trifles. this way you are guaranteed to worsen the execution time. at the same time, he will do a great job on his own, while you look at result
2 - master binding to external objects. Windows Forms DataGridView can do this https://docs.microsoft.com/ru-ru/dotnet/framework/...
in the simplest case, you can practice on cats, try arrays / lists (or you can pull up the Entity Framework, there is a database option " in memory". but only if there is data loaded from external databases, or stored in the database.. although EF is already all about async / await "out of the box")
3 - binding saves you from manually creating / deleting DataGridView rows. these are heavy operations, given that we are talking about visual elements
short summary - binding to arrays / lists / databases, and their processing in external processes, or PLINQ .. or async / await - whatever you can do

P
Peter, 2019-07-18
@petermzg

In your case, the view is constantly updated, and this is the UI part. That is, it cannot be moved to a separate thread.
What should be done here:

yourDataGridView.SuspendDrawing();
// обновление ваших полей
yourDataGridView.ResumeDrawing();

And minor improvements:
var row = this.dataGridView2.Rows[i]; // чтобы меньше проверки на индекс дергать
row.Cells[0].Value = ...;

It would be possible to take out the string.Format("{0:0.#############}"... constructions into a separate stream and enter the already prepared data into the GridView

A
asdz, 2019-07-18
@asdz

You don't need asynchrony, you need to move the heavy operation to a separate thread.
You don't have to work with the UI that's how you do it, keep your data in some separate data structure. A two-dimensional array or DataTable will do for you . Above it and perform calculations, upon completion of processing, update the UI.
The easiest way is to use BackgroundWorker, an example is here .
Well, it's not clear why 3.5k lines should be displayed on the form at the same time?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question