异步方法不将控制权返回给调用方方法

时间:2019-06-14 11:40:51

标签: c# multithreading async-await

我有以下代码

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 个答案:

答案 0 :(得分:3)

  

根据我的理解,当调用“ await Foo()”时,将创建一个线程,该线程将执行“ Foo()”方法,并且控件将返回给调用者(Main方法)。

不,绝对不是。 asyncawait不会自己创建线程。 async allows you to use await, and await will "asynchronously wait" - i.e., pause the method, return, and then resume the method when its operation completes

请注意,编译器会警告您您有一个标记为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;
}

答案 1 :(得分:-1)

由于您的Foo方法不创建任何任务,因此您的代码不会像您期望的那样发散,但按如下所示进行操作可以解决您的疑虑:

public async Task<bool> Foo()
    {
       return await Task.Run(() =>
       {
           for (int i = 0; i < 100000; i++)
           {
               Console.WriteLine("Loop");
           }
           return true;
       });
    }