• async 和 await小结


    你可以先回顾一下之前的异步操作方式(来自我们stackoverflow的总结):中文翻译:https://codeday.me/bug/20170709/39452.html

    https://stackoverflow.com/questions/1047662/what-is-asynccallback

    总的来说,第一种方式,使用我们的回调的方式;在我们的callback中处理 异步之后完成的之间; 没去堵塞我们额主线程;

    如果callback之后还有异步请求,那么久出现了我们的callback hell的 层层嵌套的模式;

    解决这种方式就是使用我们的 promise 方式的continue 的模式;

    和之前的集中方式的比较:

    https://msdn.microsoft.com/zh-cn/library/jj152938

    能够很好的说明aync 和 awati 流程的一张图;

    关于代码中是否配置我们的configure 的使用的解释:

    1)当ConfigureAwait(true),代码由同步执行进入异步执行时,当前同步执行的线程上下文信息(比如HttpConext.Current,Thread.CurrentThread.CurrentCulture)就会被捕获并保存至SynchronizationContext中,供异步执行中使用,并且供异步执行完成之后(await之后的代码)的同步执行中使用(虽然await之后是同步执行的,但是发生了线程切换,会在另外一个线程中执行「ASP.NET场景」)。这个捕获当然是有代价的,当时我们误以为性能问题是这个地方的开销引起,但实际上这个开销很小,在我们的应用场景不至于会带来性能问题。

    2)当Configurewait(flase),则不进行线程上下文信息的捕获,async方法中与await之后的代码执行时就无法获取await之前的线程的上下文信息,在ASP.NET中最直接的影响就是HttpConext.Current的值为null。

    我们在犯傻过程中,工作量最大的就是处理HttpConext.Current为null的情况。

    由于之前写代码时的幼稚与偷懒,造成了很多地方用HttpConext.Current去获取http请求相关信息。在异步化改造之后,HttpConext.Current也遍布在很多aync方法中。Configurewait(flase)之后,NullReferenceException如雨后春笋。

    原文来自这里:

    http://www.cnblogs.com/cmt/p/configure_await_false.html

    三大返回值;

    • 返回类型 - Task<TResult> 
    • 返回类型 - Task
    • 返回类型 - void

    当你添加 async 关键字后,需要返回一个将用于后续操作的对象,请使用 Task<TResult>。

    当你如果只是想知道执行的状态,而不需要知道具体的返回结果时,请使用 Task。

    当你如果在触发后,你不想管了,请使用 void。如事件处理程序。

    ps:这里还有一篇好文章;https://msdn.microsoft.com/zh-cn/magazine/jj991977.aspx

    一些异步编程的实践原理;

    1.避免 Async Void

    当 async Task 或 async Task<T> 方法引发异常时,会捕获该异常并将其置于 Task 对象上。 

    对于 async void 方法,没有 Task 对象,因此 async void 方法引发的任何异常都会直接在 SynchronizationContext(在 async void 方法启动时处于活动状态)上引发

    private async void ThrowExceptionAsync()
    {
      throw new InvalidOperationException();
    }
    public void AsyncVoidExceptions_CannotBeCaughtByCatch()
    {
      try
      {
        ThrowExceptionAsync();
      }
      catch (Exception)
      {
        // The exception is never caught here!
    throw;
      }
    }

     Async void 方法具有不同的组合语义。 返回 Task 或 Task<T> 的 async 方法可以使用 await、Task.WhenAny、Task.WhenAll 等方便地组合而成。

     返回 void 的 async 方法未提供一种简单方式,用于向调用代码通知它们已完成。 启动几个 async void 方法不难,但是确定它们何时结束却不易。 

     Async void 方法会在启动和结束时通知 SynchronizationContext,但是对于常规应用程序代码而言,自定义 SynchronizationContext 是一种复杂的解决方案。

    did you konw what is different below the code?

            static Task<string> GetStringInfoQ()
            {
                using (var wc = new System.Net.WebClient())
                {
                    return  wc.DownloadStringTaskAsync("http://www.linqpad.net"); 
                }
            }
    
            static async Task<string> getDownloadString()
            {
                using (var wc = new System.Net.WebClient())
                {
                    return  await wc.DownloadStringTaskAsync("http://www.linqpad.net"); 
                }
            }
  • 相关阅读:
    centos7 实时查看tomcat错误信息
    soapUI测试webservice(参数为xml格式的处理方式)
    四个好看的CSS样式表格
    ORM篇——有关NHibernate查询封装
    ORM篇——使用NHibernate配置对象实体的一些小问题
    c#操作XML文件的通用方法
    C#中正则表达式的使用
    C# Dictionary用法总结
    DLinq查询
    DataGrid通过DataSet保存为xml文件,并导入
  • 原文地址:https://www.cnblogs.com/mc67/p/6259297.html
Copyright © 2020-2023  润新知