提问者:小点点

试图理解异步和等待[重复]


示例代码。在下面的async方法中,IndexAsync方法是否可以在相应的get*方法完成之前返回?我试图理解async和await的基础知识,就像作者提到的他也在做的一样。

代码作者的功劳:https://www.exceptionnotfound.net/using-async-and-await-in-asp-net-what-do-these-keywords-mean/

因此,根据我现在的理解,以下是正确的:br>异步方法的好处是,当执行到get*方法的调用时,它们不必等待,因此后面的代码可以执行,当get*方法最终返回它们的值时,IndexAsync也可以最终返回。那是关于总结的吗?

public class ContentManagement
{
    public string GetContent()
    {
        Thread.Sleep(2000);
        return "content";
    }

    public int GetCount()
    {
        Thread.Sleep(5000);
        return 4;
    }

    public string GetName()
    {
        Thread.Sleep(3000);
        return "Matthew";
    }
    public async Task<string> GetContentAsync()
    {
        await Task.Delay(2000);
        return "content";
    }

    public async Task<int> GetCountAsync()
    {
        await Task.Delay(5000);
        return 4;
    }

    public async Task<string> GetNameAsync()
    {
        await Task.Delay(3000);
        return "Matthew";
    }
}



public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        ContentManagement service = new ContentManagement();
        var content = service.GetContent();
        var count = service.GetCount();
        var name = service.GetName();

        watch.Stop();
        ViewBag.WatchMilliseconds = watch.ElapsedMilliseconds;
        return View();
    }

    [HttpGet]
    public async Task<ActionResult> IndexAsync()
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        ContentManagement service = new ContentManagement();
        var contentTask = service.GetContentAsync();
        var countTask = service.GetCountAsync();
        var nameTask = service.GetNameAsync();

        var content = await contentTask;
        var count = await countTask;
        var name = await nameTask;
        watch.Stop();
        ViewBag.WatchMilliseconds = watch.ElapsedMilliseconds;
        return View("Index");
    }
}

共2个答案

匿名用户

当遇到时,进程将挂起,控制权将交还给调用方法。等待的操作既不会阻塞,也不会执行(直到稍后)。

我建议您查看这个有用的msdoc示例。

匿名用户

当您调用非异步调用时,这些调用只是普通调用。执行转移到等方法,运行的线程将休眠指定的毫秒数。调用是依次执行的,但是线程只是在每次调用时休眠。

您的方法被声明为。这在幕后所做的是建立一个用于执行异步代码的小状态机。

当您调用时,它将调用GetContentAsync,但所发生的只是函数开始执行,然后当它到达时,它返回一个承诺(给),在稍后完成执行(由该任务表示)。

稍后,您将任务。调用该状态机的。方法的其余部分(在await之后)被包装在lambda中,并在任务发出完成信号时排队执行。但是,代码的执行被挂起,运行的线程被释放回线程池(或它来自的任何地方)。例如,如果它是WinForms或WPF应用程序中的UI线程,它将返回到为UI提供服务。

任务完成后,代码的其余部分再次开始运行。在UI应用程序(如WinForms或WPF)中,可以保证如果您在UI线程上启动,则其余代码将在同一线程上运行。在其他环境中,担保可能较少涉及。

如果您曾经用JavaScript编写过web页面并对服务器进行过AJAX回调,那么您将设置要调用的位置,参数是什么,以及调用返回时要运行的函数。一个方法调用(或任务)有点像这样。它使用参数调用函数,但将当前函数的其余部分包装成一个表单,该表单将在任务完成时执行。

在UI应用程序中,Async/Await的好处是显而易见的--它允许顺序编程,同时仍然将处理从UI线程中分离出来。

在ASP.NET环境中就不那么明显了。线程是web服务器应用程序中的珍贵商品。在web应用程序中,Async/Await为您提供了一种无需绑定与请求相关联的线程就可以进行后台处理(其中大部分是自然异步的--比如对某个服务的WebAPI请求)的方法。当您等待一个任务时,您的线程会返回到池中。当任务完成时,代码返回一个线程并继续使用

相关问题