async\await при считывании таблицы

143
14 ноября 2020, 21:10

Есть метод, который считывает ячейки таблицы xlsx и записывает их в List. При синхронном выполнении программа зависает на 20-30 секунд пока не закончится операция.

Читал про async await на хабре. Но так и не смог понять как воспользоваться данной технологией в своем методе.

Код метода,

public static  List<Drom_object> ReadMassive(string path) // метод, вызываемый при чтении таблицы.
{
    drom_massive = new List<Drom_object>(); // инициализируем лист.
    try { 
    FileInfo existingFile = new FileInfo(path);
    using (ExcelPackage package = new ExcelPackage(existingFile))
    {
        ExcelWorksheet worksheet = package.Workbook.Worksheets[1];   // данные всегда на первом листе. 
        int row = GetDimensionRows(worksheet); // узнаем сколько строк в таблице.

        for (int r = 1; r <= row; r++) // считываем все строки
        {
            string[] buff = new string[18]; // создаем буфер строки эксель из 18 ячеек. (18 колонок)
            for (int i = 1; i < 19; i++) // сканируем 18 колонок (с 1 по 18)
            {
                try
                {
                    Value = null; //убираем мусор
                    Value = worksheet.Cells[r, i].Value.ToString(); // получаем значение ячейки
                }
                catch (NullReferenceException)
                {
                    Value = "empty";
                    System.Console.WriteLine("JDC: обработано пустое значение ячейки");
                }
                buff[i-1] = Value.ToString(); // Засовываем отсканированные стролбцы в буфер
            }
            if (buff[0] == "empty" && buff[1] == "empty" && buff[2] == "empty" && buff[3] == "empty" && buff[4] == "empty" && buff[5] == "empty")
            // если первые пять ячеек пустые - значит остальные проверять смысла нет, т.к. это пустая строка.
            {
                // ничего не делаем
            }
            else // но если в строке что то есть, надо понять, либо это глобальная категория, либо строка заголовков либо товарная строка.
            {
                if (buff[0] != "empty" && buff[1] == "empty" && buff[2] == "empty") // если только первая ячейка не пустая значит это ЗАГОЛОВОК (global_category).
                {
                    global_category = buff[0];
                }
                else 
                {
                    if (!buff[0].Contains("Наименование товара") || !buff[2].Contains("Марка") || !buff[17].Contains("Фотография"))  // Если это не строка категорий
                    {
                        // Значит это строка с товарной позицией, и нам пора добавлять товар в ListDrom
                        Drom_object new_good = new Drom_object(); //класс дром_обьект принимает 16 позиций. выбираем из буфера нужные и вставляем
                        new_good.SetData(
                            buff[0],
                            buff[1],
                            buff[2],
                            buff[3],
                            buff[5],
                            buff[6],
                            buff[7],
                            buff[8],
                            buff[9],
                            buff[11],
                            buff[12],
                            buff[13],
                            buff[14],
                            buff[16],
                            buff[17],
                            global_category);
                        drom_massive.Add(new_good); // наполняем обьект нужными данными и суем их в лист.
                    }
                }
            }
        }
    }
    }
    catch (System.ArgumentNullException)
    {
    }
    read_ok = true; // после того как наполнение закончено, поднимаем флаг
    return drom_massive; // Возвращаем наш массив обьектов
}  

Как мне сделать этот метод асинхронным? Куда добавить await...

В во всех примерах await ставится к методу который уже где то за рамками примера определен и прекрасно работает.

Когда я попытался создать асинхронный метод который вызывал бы асинхронно вышеописанный метод - также получил ошибку при компиляции...

У меня еще несколько таких же методов которые участвуют в I\O. Если бы я понял как сделать этот, я бы смог по такому же принципу сделать остальные,

И еще вопрос, хотелось бы вызывать этот асинк метод из класса формы, чтобы не заморачиваться с доступом к Progress bar.

Если не сложно приведите небольшой скетч в котором асинхронно выполнялось бы считывание данных, и было реализована отправка статуса операции (процент выполнения) в свойство какой нибудь формы.

Answer 1

Пока не удалось разобраться с Acync Await вместо этого был использован более старый класс Thread:

Вызов метода происходит так:

  private void Button2_Click(object sender, EventArgs e)
    {
        button2.Enabled = false;

        Thread t = new Thread(delegate () { Work_with_massive.ReadMassive(this, Work_with_massive.GlobalPath); });
        t.Start();   
    }

К сожалению данный метод (подход) не лишен недостатков: 1. Таким образом нельзя вернуть какие то данные из метода, сообщить можно методу только один параметр типа Object (насколько я понял) 2. И нет отчетности о проценте исполнения задачи.

READ ALSO
Как подключиться к базе данных PostgreSQL?

Как подключиться к базе данных PostgreSQL?

Проблема такая, решил создать простое приложение по отборке юзеров

126
Эмуляция нажатия ctrl + v

Эмуляция нажатия ctrl + v

Необходимо эмулировать нажатие данных клавиш вне формы

131
С# EmguCV ошибка &ldquo;OpenCV: type == CV_32F || type == CV_64F&rdquo;

С# EmguCV ошибка “OpenCV: type == CV_32F || type == CV_64F”

Нужен метод, который будет инвертировать видеоВ метод передается текущий кадр

101
Авторизация на сайтах (POST запросы c#)

Авторизация на сайтах (POST запросы c#)

В общем походу написания проекта возникла потребность совершать авторизацию на нескольких сайтахЕдиного подхода тут не будет(или я его...

121