简体   繁体   中英

Cannot await async task

I have a method called StartAsync which await different task, this is the design:

public async Task StartAsync(int instance)
{
    await SomeController.Foo();
    await AnotherController.Foo2();
}

Now I need to run the StartAsync method multiple times, so I have created different Task , in this way I can manage a single execution of the Task of StartAsync :

Task bot1 = new Task(async () => { await new Bot().StartAsync(1); });

Task bot2 = new Task(async () => { await new Bot().StartAsync(2); });

these Tasks can be started by the input, essentially, if the user press 1 then the bot1 Task will start:

public async Task<bool> StartBotInstanceAsync(int instance)
{
     try  
     {
          switch(instance)
          {
              case 1:
                  await bot1.Start(); //<- Problem here
                  break;

              case 2:
                  bot2.Start(); 
                  break;
          }

          return true;
     }
     catch(Exception ex)
     {
         Logger.Info(ex.ToString());
         return false;
     }
}

Essentially I need to write a log when an exception happen in side the try catch block, but for doing this I need to await the Task result, unfortunately I get this error:

Cannot await void

on await bot1.Start();

How can I manage the exception in this type of situation?

If you wish to do it with your current structure then you will need 2 separate statements.

case 1:
    bot1.Start();
    await bot1;
    break;

If you want to use multiple bot instances, store them in an array and use the instance parameter as the index, eg :

_bots=new[]{ new Bot(),new Bot()};

public async Task<bool> StartBotInstanceAsync(int instance)
{
     try  
     {
          await _bots[instance-1].StartAsync();
          return true;
     }
     catch(Exception ex)
     {
         Logger.Info(ex.ToString());
         return false;
     }
}

Or even better :

public async Task<bool> StartBotInstanceAsync(Bot bot)
{
     try  
     {
          await bot.StartAsync();
          return true;
     }
     catch(Exception ex)
     {
         Logger.Info(ex.ToString());
         return false;
     }
}

var myBot=_bots[instance-1];
var started=await StartBotInstanceAsync(myBot);

More complex flows can be created easily by using async functions that take the bot as a parameter, eg :

public async Task SomeComplexFlow(Bot bot)
{
    try
    {
        await bot.StartAsync();
        await bot.DoSomething();
        ...
    }
    catch(Exception exc)
    {
        ...
    }
}


var myBot=_bots[instance-1];
await SomeComplexFlow(myBot);

It's possible to await multiple tasks for completion too. One coud use Task.WhenAll to wait for all bots to terminate, eg :

await Task.WhenAll(_bots[0].StopAsync()...);

Or, better yet :

var tasks=_bots.Select(bot=>bot.StopAsync());
await Tasks.WhenAll(tasks);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM