Асинхронный метод не возвращает управление обратно вызывающему методу - PullRequest
0 голосов
/ 14 июня 2019

У меня есть следующий код

class Program
{
    public  async  Task<bool> StartMyTask()
    {
        await Foo();

        return true;

    }

    public async Task<bool> Foo()
    {

        for (int i = 0; i < 1000000; i++)
        {
            Console.WriteLine("Loop");
        }
        return true;

    }


    static void Main(string[] args)
    {
        Program obj = new Program();

        var myTask = obj.StartMyTask();     
        Console.WriteLine("Before Task Return");                                    


        Console.ReadLine();
    }
}

Согласно моему пониманию, когда вызывается "await Foo ()", будет создан поток, который будет выполнять метод "Foo ()", и элемент управления будет возвращен вызывающей стороне (метод Main).

Учитывая это, перед выполнением метода Foo () необходимо напечатать «Перед возвратом задачи». Но этого не происходит, сначала метод «Foo ()» завершается, а затем отображается «Перед возвратом задачи».

Ответы [ 2 ]

3 голосов
/ 14 июня 2019

Согласно моему пониманию, когда вызывается "await Foo ()", будет создан поток, который будет выполнять метод "Foo ()", и элемент управления будет возвращен вызывающей стороне (метод Main).

Нет, абсолютно нет.async и await не создают потоки самостоятельно.async позволяет вам использовать await, а await будет "асинхронно ждать", то есть приостановить метод, вернуться и затем возобновить метод после завершения его операции .

Обратите внимание, что компилятор предупреждает вас, что у вас есть метод, помеченный async, но он будет работать синхронно .Таким образом, компилятор уже говорит вам, что именно не так.

Если вы хотите использовать фоновый поток, вы можете использовать Task.Run для вызова синхронного Foo метода:

public async Task<bool> StartMyTask()
{
  await Task.Run(() => Foo());
  return true;
}

public bool Foo()
{
  for (int i = 0; i < 1000000; i++)
  {
    Console.WriteLine("Loop");
  }
  return true;
}
0 голосов
/ 14 июня 2019

Поскольку ваш метод Foo не создает никакой задачи, ваш код не будет расходиться, как вы ожидаете, но выполнение следующих действий решает ваши проблемы:

public async Task<bool> Foo()
    {
       return await Task.Run(() =>
       {
           for (int i = 0; i < 100000; i++)
           {
               Console.WriteLine("Loop");
           }
           return true;
       });
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...