ElemAnybody
@ElemAnybody

C# (winform) как засунуть async и await в мой код?

У меня есть код, который просто умирает на своей задачи (интерфейс ложиться на минут 10) при обработки +- 3500 строк данных. В голову пришла идея сделать асинхронность выполнения это работы. Проблема в том, что я не особо разобрался как использовать асинхронность в таких примерах как у меня!
код С#:
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 хранятся цифры (double), которые используются в расчётах
В datagridview2 ответы которые прошли в расчётах
spoiler
Было бы идеально, если кто-то помог мне с этим кодом + правильно поставил collect и прочие детали которые очищают мусор, ибо после такого расчёта у меня забит пк кешом почти в 1000мб

Но если, есть другой какой-то способ ускорить этот процесс, то пишите.
  • Вопрос задан
  • 288 просмотров
Пригласить эксперта
Ответы на вопрос 3
mindtester
@mindtester Куратор тега C#
https://youtu.be/UtO6HIp1908?list=RDUtO6HIp1908
1 - совет - не дергайте сборщик мусора по мелочам. этим вы гарантированно ухудшаете время выполнения. в то же время он и сам великолепно справится, пока вы будете рассматривать результат

2 - осваивайте binding к внешним объектам. Windows Forms DataGridView это умеет https://docs.microsoft.com/ru-ru/dotnet/framework/...

в простейшем случае можете потренироваться на кошечках попробовать массивы/списки (а можно и Entity Framework подтянуть, там есть вариант БД "in memory". но только если есть данные загружаемые из внешних БД, или сохраняемые в БД.. хотя EF уже весь на async/await "из коробки")

3 - binding из бавит вас от рукопашного создания/удаления строк DataGridView. это тяжеловестные операции, учитывая что речь о визуальных эелементах

краткое резюме - binding к массивам/спискам/бд, а их обработка во внешних процессах, или PLINQ.. или async/await - что осилите
Ответ написан
petermzg
@petermzg
Самый лучший программист
В вашем случае идет постоянное обновление view, а это UI часть. То есть вынести в отдельный поток нельзя.
Что тут стоит сделать:
yourDataGridView.SuspendDrawing();
// обновление ваших полей
yourDataGridView.ResumeDrawing();

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

Можно бы и конструкции string.Format("{0:0.#############}"... в отдельный поток вынести и уже подготовленные данные внести в GridView
Ответ написан
@asdz
Асинхронность вам не нужна, нужно вынести тяжелую операцию в отдельный поток.
Работать с UI вот как вы делаете не надо, держите свои данные в какой нибудь отдельной структуре данных. Вам подойдет двумерный массив или DataTable Над ней и выполняйте вычисления, по завершении обработки, обновите UI.

Проще всего воспользоваться BackgroundWorker, пример тут.
Ну и непонятно, зачем 3,5к строк одновременно отображать на форме?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы