How to use async/await in void return methods?

Asked

Viewed 929 times

0

I have a problem in my application, where due to the large volume of processing, my Form lock. During my researches I found that a method async resolves this, however the functions performed on my "run" button return void, this way I can not use the await because I do not know when the execution of the function will end(because it does not return a task).

Is there any way to use Thread or Task in this scenario? Unlocking the form and dividing the processing?

EDIT AFTER SUGGESTIONS:

Man for was this way after the suggestions:

for (i = iTemp; i < evolucoes; i++)
        {
            iTemp++;

            lbEvolucoes.Text = i.ToString();
            lbEvolucoes.Refresh();

            await Task.Factory.StartNew(() =>
              {
                  pop = AG.executeGA(pop);
              });


            // pop = AG.executeGA(pop);

            //Limpar o grafico
            zedMedia.GraphPane.CurveList.Clear();
            zedMedia.GraphPane.GraphObjList.Clear();

            double mediaPop = pop.getMediaPop();
            mediaPopulacao.Add(i, mediaPop);

            double bestFitness = pop.getBest().getFitness();

            #region Começo do dois opt

            await Task.Factory.StartNew(() =>                 
            {

                var tasks = new List<Task>();
                for (int j = 0; j < 100; j++)
                    tasks.Add(Task.Run(() =>
                    {
                        Utils.TwoOpt(pop.getBest());
                    }));
            });

            #endregion

            lbMenorDistancia.Text = bestFitness.ToString();
            lbMenorDistancia.Refresh();

            LineItem media = paneMedia.AddCurve("Média", mediaPopulacao, Color.Red, SymbolType.None);

            //Print linhas a cada 6 evolucoes
            if (i % 6 == 0 && bestFitness < bestAux)
            {
                bestAux = bestFitness;
                g.Clear(Color.White);
                plotLines(pop, Color.Blue);
                plotPoints();
            }

            zedMedia.AxisChange();
            zedMedia.Invalidate();
            zedMedia.Refresh();
        }

It’s like this, it’s cool?

  • You’re not getting back one async void? Another solution is to use the Task.Factory

  • Then no use returning a void, because I would have to tell my form to stay working while the function does not finish processing , this I would do with the await, but with void return it is not possible to call the Await, because the function needs to return a Task saying that it is over, Factory tmb did not give :/

  • Make the calling method async and put await before the call to a method does not cause the code of the called method to be executed asynchronously. One possible way is to use Task.Factory.StartNew(metodo()) to call him.

2 answers

2


A method that returns void can also be asynchronous, hence you can also use the await within it.

To make it asynchronous, include the prefix async in your header, see an example:

private async void button1_Click(object sender, EventArgs e)

One way not to make it run on "top-level" (protected from unobserved exceptions), is to use the Task.Factory, see:

private async void button1_Click(object sender, EventArgs e)
{
    await Task.Factory.StartNew(() =>
    {
        //métodos aqui
    });
}
  • From what I understand of the question async in StartNew(async () => is the most.

  • If you don’t say Action is async, you won’t be able to use the await within it @ramaral

  • Yes, but for that the method, to call inside the Startnew, has to return a Task. AP says it returns void.

  • Thanks for the touch, I’ll edit. @ramaral

  • Francis, thank you for your help, as seen above, I posted the code of how my for got, what you found?

  • @Guilhermeprado I recommend you put all the code inside the Task created with Factory, including the for.

  • @Guilhermeprado If the answer solved your problem, please mark it as correct! =)

  • @Francisco This right I create a task list to increase function processing?

  • @Guilhermeprado If it’s all thread-safe, yes. But remember that to wait for the execution you must use the await. Take a look at Task.WhenAll

Show 4 more comments

0

Just declare your method as async and put the type of return Task, that would be a void multithreaded.

Below is an example:

using System.Threading.Tasks;
using System.Net.Http;

public async Task ExecutarMetodoAsync()
{
    using (var httpClient = new HttpClient())
    {
        // Exemplo
        await httpClient.PostAsync("", null);
    }
}

If you need to return some value you define the return type of the Task, example below:

using System.Threading.Tasks;
using System.Net.Http;

public async Task<string> ExecutarMetodoAsync()
{
    using (var httpClient = new HttpClient())
    {
        // Exemplo
        return await httpClient.GetStringAsync("");
    }
}
  • thanks for the help, what you found?

Browser other questions tagged

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