Help with Async C# / Winforms

Asked

Viewed 93 times

1

good morning!

I set up a small study project where I collect data from a site and game for a Datagridview using Selenium. I have 3 classes

Robot.Cs -> Where I have the methods of navigation and data collection.

//NAVEGAR PARA O SITE(URL)
public void GoToUrl(string Url)
{
    RoboDriver.Navigate().GoToUrl(Url);
}
//PROCURAR POR XPATH LER E RETORNAR VALOR
public string ReadByXPath(string XPath, string attribute)
{
    string SetRead;
    Wait.Until(d => RoboDriver.FindElementByXPath(XPath));
    SetRead = RoboDriver.FindElementByXPath(XPath).GetAttribute(attribute);
    return SetRead;
}

Robotnavigation.Cs -> Responsible for navigation.

        //METODO PARA BUSCAR E PREENCHER AS COTAÇÕES DO DATAGRIDVIEW
    public void GetQuotes(DataGridView dataGridView, ProgressBar progressBar)
    {
        //ZERAR BARRA DE PROGRESSO
        progressBar.Value = 0;
        //DEFININDO VALOR DA BARRA DE PROGRESSO
        progressBar.Maximum = dataGridView.RowCount;
        //PERCORRER REGISTROS DO DATAGRIDVIEW
        foreach (DataGridViewRow row in dataGridView.Rows)
        {
            //TRAVAR DATAGRIDVIEW
            dataGridView.AllowUserToAddRows = false;
            string codActive = row.Cells[0].Value.ToString();
            //MONTAR URL DE NAVEGAÇÃO COM CÓDIGO OBTIDO
            string url = "https://www.fundamentus.com.br/detalhes.php?papel=" + codActive;
            //NAVEGAR PARA SITE (URL)
            GoToUrl(url);
            //PREENCHER COLUNA DO DATAGRIDVIEW COM A COTAÇÃO OBTIDA NO SITE
            row.Cells[1].Value = ReadByXPath("/html/body/div[1]/div[2]/table[1]/tbody/tr[1]/td[4]/span", "innerHTML");
            //INCREMENTAR BARRA DE PROGRESSO
            progressBar.PerformStep();
        }
        //FECHAR ROBO
        RobotQuit();
        //HABILITAR DATAGRIDVIEW
        dataGridView.AllowUserToAddRows = true;
    }
}

Form1.Cs -> Where I run navigation via a button.

        private void bntPlay_Click(object sender, EventArgs e)
    {
        RobotNavigation robotNavigation = new RobotNavigation();
        robotNavigation.GetQuotes(dgvMain, pBar);
    }

I would like a help to make this project asynchronous so that the form and components do not lock while the robot navigates, collects data and works with the components passed via parameter.

  • 1

    You must implement a thread that runs the logic of data collection, so the application thread will not be locked until the end of the operation. Have a look here https://docs.microsoft.com/pt-br/dotnet/api/system.threading.threadpool.queueuserworkitem?view=netframework-3.5

2 answers

0

You will need to use a task to run the logic:

private async void bntPlay_Click(object sender, EventArgs e)
{
    Task tks = Task.Run(() => 
    {
        RobotNavigation robotNavigation = new RobotNavigation();
        robotNavigation.GetQuotes(dgvMain, pBar);
    });

    await tks;
}
  • Hello! Good morning! I’ve tried this by involving the components in a void{} and invoking using Invoker.... but it never happened... I believe I’ll have to change this structure to work...

0

good morning!

I ended up changing the structure of the project to get the result I expected and so I only had the files Robot and Form1.

Follow repository if you want to see the final result.

https://github.com/lbert1/Pepe-Robot

Form1.Cs

   public void GetQuotes()
    {
        Robot robot = new Robot();
        MethodInvoker invPBarStart = delegate
        {
            //ZERAR BARRA DE PROGRESSO
            pBar.Value = 0;
            //DEFININDO VALOR DA BARRA DE PROGRESSO
            pBar.Maximum = dgvMain.RowCount;              
        };
        Invoke(invPBarStart);
        //PERCORRER REGISTROS DO DATAGRIDVIEW
        foreach (DataGridViewRow row in dgvMain.Rows)
        {
            MethodInvoker invDgvStart = delegate
            {
                //TRAVAR ADICONAR NO DATAGRIDVIEW
                dgvMain.AllowUserToAddRows = false;            
            };
            Invoke(invDgvStart);
            string codActive = row.Cells[0].Value.ToString();
            //MONTAR URL DE NAVEGAÇÃO COM CÓDIGO OBTIDO
            string url = "https://www.fundamentus.com.br/detalhes.php?papel=" + codActive;
            //NAVEGAR PARA SITE (URL)
            robot.GoToUrl(url);
            //PREENCHER COLUNA DO DATAGRIDVIEW COM A COTAÇÃO OBTIDA NO SITE
            row.Cells[1].Value = robot.ReadByXPath("/html/body/div[1]/div[2]/table[1]/tbody/tr[1]/td[4]/span", "innerHTML");
            //INCREMENTAR BARRA DE PROGRESSO
            MethodInvoker invPBarStep = delegate
            {
                pBar.PerformStep();
            };
            Invoke(invPBarStep);
        }
        //FECHAR ROBO
        robot.RobotQuit();
        MethodInvoker invDgvEnd = delegate
        {            
            //HABILITAR DATAGRIDVIEW
            dgvMain.AllowUserToAddRows = true;
        };
        Invoke(invDgvEnd);
    }

    private async void bntPlay_Click(object sender, EventArgs e)
    {
        //CHAMAR METODO GETQUOTES DE FORMA ASSINCRONA
        await Task.Run(() => GetQuotes());
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.