简体   繁体   English

C#异步和等待流

[英]C# Async and Await flow

I am trying to understand async and await flow . 我试图了解异步并等待流程。 Started looking at code from 开始查看代码
John Atten's blog about Owin and Katana . John Atten关于Owin和Katana 的博客 While trying to look at the execution steps I found few steps in the flow (Steps 9 and 16), which I am not able to understand as to why the execution will traverse. 在尝试查看执行步骤时,我在流程中找到了几个步骤(步骤9和16),我无法理解为什么执行将遍历。

code: 码:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Owin;
using Microsoft.Owin.Hosting;
using Owin;
namespace KatanaConsole
{
    //use an alias for OWIN APPFunc
    using AppFunc= Func<IDictionary<string,object>,Task>;
    class Program
    {
        static void Main(string[] args)
        {

            var uri = "http://localhost:8080";

            using ( WebApp.Start<StartUp>(uri))
            {
                Console.WriteLine("Web Server started on port 2323");
                 Console.WriteLine("Server Started; Press enter to Quit");
                Console.ReadLine();
            }
        }
    }

    public class StartUp
    {
        public void Configuration(IAppBuilder appBuilder)
        {
        var firstMiddleware= new Func<AppFunc,AppFunc>(FirstMiddleware);
        var secondMiddleware = new Func<AppFunc, AppFunc>(SecondMiddleware);

        appBuilder.Use(firstMiddleware);
        appBuilder.Use(secondMiddleware);

        }


        public AppFunc FirstMiddleware(AppFunc next)
        {

            AppFunc appFunc = async environment =>
            {
                IOwinContext context = new OwinContext(environment);
                await context.Response.WriteAsync("<h1> Middleware:1 ->  Hello from X1</h1>");
                await next.Invoke(environment);
            };
            return appFunc;
        }

        public AppFunc SecondMiddleware(AppFunc next)
        {

            AppFunc appFunc = async (IDictionary<string, object> environment) =>
            {
                IOwinContext context = new OwinContext(environment);
                await context.Response.WriteAsync("<h1> Middleware:2 ->  Hello from X2</h1>");
                await next.Invoke(environment);
            };
            return appFunc;
        }
    }


}

The code flow when I try to access localhost:8080 我尝试访问localhost时的代码流:8080

Flow: 流:

Enters ->First Middleware 进入 - >第一个中间件

  1. IOwinContext context = new OwinContext(environment);
  2. await context.Response.WriteAsync("<h1> Middleware:1 -> Hello from X1</h1>"); // Response Sent to browser
  3. await next.Invoke(environment);

Enters -> Second Middleware 进入 - >第二个中间件

  1. IOwinContext context = new OwinContext(environment);

  2. await context.Response.WriteAsync("<h1> Middleware:2 -> Hello from X2</h1>");// Response Sent to browser

  3. await next.Invoke(environment);

Enters (Back to Calling Method) -> First Middleware 进入(回到呼叫方法) - >第一个中间件

  1. await next.Invoke(environment);

  2. Exits -> FirstMiddleWare 退出 - > FirstMiddleWare

Re-Enters ->First Middleware 重新进入 - >第一个中间件

  1. IOwinContext context = new OwinContext(environment);

  2. await context.Response.WriteAsync("<h1> Middleware:1 -> Hello from X1</h1>"); // No Response Sent to browser

  3. await next.Invoke(environment);

Re-Enters -> Second Middleware 重新进入 - >第二个中间件

  1. IOwinContext context = new OwinContext(environment);

  2. await context.Response.WriteAsync("<h1> Middleware:2 -> Hello from X2</h1>");// No Response Sent to browser

  3. await next.Invoke(environment);

Re-Enters (Back To Calling Method) -> First Middleware 重新进入(返回呼叫方法) - >第一个中间件

  1. await next.Invoke(environment);

  2. Exits -> FirstMiddleWare 退出 - > FirstMiddleWare

Execution Stops My question is why does it traverse again Steps 9 and 16? 执行停止我的问题是为什么它再次遍历步骤9和16?

and add to it, even though Step 9 and 16 are traversed , response does not change. 并添加到它,即使遍历步骤9和16,响应也不会改变。 So I am guessing it is doing some post condition check there. 所以我猜它在那里进行一些后置条件检查。

** Edit - 1 ** **编辑 - 1 **

Added All steps traversed to make it more clear( added steps 9 to 16) 添加了所有遍历的步骤以使其更加清晰(添加了步骤9到16)

Steps 9 to 16 are traversed because of an automatic second request you get from the browser for the favicon . 遍历步骤9到16是因为您从浏览器获取了favicon的自动第二个请求。 If you pay attention to the context.Request.Path you will notice that the first round through the middleware is for "/" and the second for "/favicon.ico". 如果您注意context.Request.Path,您会注意到第一轮中间件是“/”,第二轮是“/favicon.ico”。 Actually the behavior depends on the browser you are using to make the request. 实际上,行为取决于您用于发出请求的浏览器。 I've tested with the most resent version of a couple of browsers and with Webkit browsers (Chrome and Opera) plus IE i always get a request for the favicon. 我已经使用最新版本的几个浏览器和Webkit浏览器(Chrome和Opera)以及IE测试我总是得到一个关于favicon的请求。 With FF i do get it just the first time and it's being cached. 使用FF我只是第一次得到它并且它被缓存。 And with Edge - it's not been requested at all. 而使用Edge - 根本没有要求它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM