关于任务、异步和等待的多线程

sag*_*y36 2 c# multithreading asynchronous task async-await

我有以下代码,只是想确保我在高层次上拥有多线程的概念。

public async Task<List<Category>> GetProjectsByCategoryIDAsync(Int16 categoryid)
    {
        try
        {
            using (YeagerTechEntities DbContext = new YeagerTechEntities())
            {
                DbContext.Configuration.ProxyCreationEnabled = false;
                DbContext.Database.Connection.Open();

                var category = await DbContext.Categories.Include("Projects").Where(p => p.CategoryID == categoryid).ToListAsync();

                return category;
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
Run Code Online (Sandbox Code Playgroud)

以下是我的理解:

  1. async - 声明一个异步运行的方法,而不是同步运行。
  2. 任务 - 声明一个在单个线程上作为任务运行的方法
  3. await - 任务等待操作完成。

我有点模糊的地方是 await 关键字。显然,异步编程的好处是该方法不需要等待任务完成,然后另一个请求就在它后面。但是使用 await 关键字,任务会一直等到操作完成。

通过同步编程,一切都以顺序模式进行处理。

这种方法如何允许请求同时进入并以比同步编程更快的方式执行?

我只需要一个高层次的解释来理解这个概念。

非常感谢。

dca*_*tro 5

考虑以下代码:

    public async Task DoSomething()
    {
        Console.WriteLine("Begin");
        int i = await DoSomethingElse();
        Console.WriteLine("End " + i);
    }

    public Task<int> DoSomethingElse()
    {
        return new Task<int>(() =>
        {
            // do heavy work
            Thread.Sleep(1000);
            return 1;
        });

    }
Run Code Online (Sandbox Code Playgroud)

通过同步编程,一切都以顺序模式进行处理。

上面的代码是异步的,但仍然是顺序的。该代码与其同步版本(例如,public int DoSomethingElse)之间的区别在于,当您执行 时await DoSomethingElse,主线程将被释放以执行其他工作,而不是阻塞等待 DoSomethingElse 完成。

实际发生的是:您的异步 DoSomething 方法将在线程 A 上运行并被分成两部分。

  • 第一部分将打印“开始”并进行异步调用,然后返回。
  • 第二部分将打印“结束”

在方法的第一部分执行后,线程 A 将可以自由地做其他工作。同时,线程 B 将执行执行一些繁重工作的 lambda 表达式。每当线程 B 完成时,您的方法的第二部分将被安排在线程 A 上运行,并且将打印“End”。

请注意,当线程 B 执行繁重的工作时,线程 A 可以自由地做其他事情。

这种方法如何允许请求同时进入并以比同步编程更快的方式执行?

在 ASP.NET MVC 等框架中,您的应用程序具有有限数量的线程可用于处理传入请求(我们称之为“请求线程”)。通过将繁重的工作委托给其他线程并等待,您的请求线程将可以在繁重的工作完成时自由地处理更多传入的请求。

该图虽然复杂,但说明了执行异步工作的线程的执行/暂停流程:

在此处输入图片说明

注意第 6 步线程是如何被让出的,然后第 7 步恢复方法的执行。如您所见,await关键字有效地将方法一分为二。