Use synchronous or asynchronous tasks to collect print counters

Asked

Viewed 113 times

1

I am trying to develop a process that performs the collection of some printers counters via SNMP protocol, I thought to use Threads to perform this process, refatorei to use tasks, but I do not know if I should use an async await for this task, in this case I find myself a little confused if I am developing this method in the best way. Follows code of method:

private void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        using (ImpressoraDAO dao = new ImpressoraDAO())
        {
            var impressoras = dao.Listar().ToList();
            var impressorasTasks = impressoras.Select(impressora =>
            {
                return Task.Factory.StartNew(() =>
                {
                    if (impressora.IsConected())
                    {
                        using (ContadorDAO contadorDao = new ContadorDAO())
                        {
                            var contador = new Contador();
                            contador.Id = DateTime.Now;
                            contador.ImpressoraId = impressora.Id;
                            contador.QuantidadePaginas = Convert.ToInt64(OperacaoSNMP.ObterObjetoOID(IPAddress.Parse(impressora.Ip), OID.CONTADADOR_TOTAL));
                            contadorDao.Adicionar(contador);
                        }
                    }
                });
            }).ToArray();

            Task.WhenAll(impressorasTasks);
        }
    }

How can I improve this code ? Should I let it so or would it be better to use an async await ?

1 answer

0


In this case it might be better not to use Task. Tasks work best when Voce has operations I\O asynchronous. Because as the I\O not processed the CPU can continue to do other things.

One thing I noticed is that the method contadorDao.Adicionar(contador) may be poorly implemented. I don’t know what this method does. But if he does a database query then it would make sense for him to be asynchronous. And then Voce should use tasks.

A better approach to current code would be to use the Parallel.ForEach

var impressoras = dao.Listar().ToList();
Parallel.ForEach(impressoras, impressora => {
    if (impressora.IsConected())
    {
        using (ContadorDAO contadorDao = new ContadorDAO())
        {
            var contador = new Contador();
            contador.Id = DateTime.Now;
            contador.ImpressoraId = impressora.Id;
            contador.QuantidadePaginas = Convert.ToInt64(OperacaoSNMP.ObterObjetoOID(IPAddress.Parse(impressora.Ip), OID.CONTADADOR_TOTAL));
            contadorDao.Adicionar(contador);
        }
    }
});

You will ultimately have to resort to profiling techniques to see what the best performing approach is for your scenario.

  • Actually my DAO classes are only one layer between the Entityframeworkcore and the business rule, within the counter I use the context to insert this counter into a database! The counter has a key composed by the printer id and the time of collection! I hope I have clarified this question ! So it is better to use async ?

  • @Lucasbarbosa Yes. But for that Voce has to use the SaveChangesAsync()

  • I will redo the code following this advice Bruno to see how behaved and see if I really got the idea! And I would like to thank you from now on!

Browser other questions tagged

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