Не могу дождаться асинхронной задачи - PullRequest
0 голосов
/ 29 октября 2018

У меня есть метод с именем StartAsync, который ожидает другую задачу, это дизайн:

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

Теперь мне нужно запустить метод StartAsync несколько раз, поэтому я создал другой Task, так что я могу управлять одним выполнением Task из StartAsync:

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

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

эти Tasks могут быть запущены с помощью ввода, по сути, если пользователь нажмет 1, тогда начнется задача bot1:

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;
     }
}

По сути, мне нужно написать журнал, когда в блоке try catch происходит исключение, но для этого мне нужно дождаться результата Task, к сожалению, я получаю эту ошибку:

Не может ждать пустоты

на await bot1.Start();

Как я могу справиться с исключением в такой ситуации?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Если вы хотите использовать несколько экземпляров ботов, сохраните их в массиве и используйте параметр instance в качестве индекса, например:

_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;
     }
}

Или даже лучше:

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);

Более сложные потоки могут быть легко созданы с помощью async функций, которые принимают бота в качестве параметра, например:

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


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

Возможно также дождаться завершения нескольких задач. Один кулд использует Task.WhenAll, чтобы дождаться завершения всех ботов, например:

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

Или, еще лучше:

var tasks=_bots.Select(bot=>bot.StopAsync());
await Tasks.WhenAll(tasks);
0 голосов
/ 29 октября 2018

Если вы хотите сделать это с вашей текущей структурой, вам понадобятся 2 отдельных утверждения.

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