将方法转变为等待

Zuz*_*zlx 1 c# asynchronous async-await

我正在努力巩固我对异步和等待的理解.我终于理解了关于上下文切换的全部内容(这都是魔术).我写了一个简短的winform程序来玩它.请考虑以下事项

  private async void button1_Click(object sender, EventArgs e)
      {

        output.Text = "start";
        var intRet = await Task.Run(() => RunALot());
        output.Text += "   after run  ";
        output.Text += intRet.ToString();


    }

    private async Task<int> RunALot ()
    {

        int temp = 0;
        for (int ini = 0; ini <= 40000; ini++)
        {
            temp += ini;
        }
        return temp;
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经有一个Task.Run我正在调用的时候我RunALot.是否需要将其内部包装RunALot到另一个内部Task.Runawait使其真正异步?嵌套上下文有任何性能影响 - 我可以在多大程度上嵌套上下文?

Ser*_*rvy 5

RunALot实际上不是异步操作.您已使用async关键字对其进行了标记,但该方法的实现只是同步进行了大量工作,然后Task在最后返回已完成的工作.您的代码生成编译器警告,告诉您这一点.

因为RunALot是同步的,所以如果要创建一个Task表示在另一个线程上异步完成的同步工作.你这样做.但是,RunALot你应该更改它的签名以使其不返回a ,而不是说谎并声称它是异步的Task,因此任何调用它的人都清楚它实际上并不是异步操作.


Ale*_*hev 5

请记住async 关键字不会使您的代码异步运行。正如Servy 已经提到的,RunALot() 不是异步方法。如果你想让它异步,你可以做这样的事情:

public static Task<int> RunALot()
{
    return Task.Run(() =>
    {
        int temp = 0;
        for (int ini = 0; ini <= 40000; ini++)
        {
            temp += ini;
        }
        return temp;
    });
}
Run Code Online (Sandbox Code Playgroud)

这就是您可以在 button1_Click 中调用它的方式:

var intRet = await RunALot();
Run Code Online (Sandbox Code Playgroud)