async和awit

[C#] 谈谈异步编程async await

个人编写的demo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace UmengPushDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            fun1();
            Console.WriteLine("3");
            Console.ReadKey();
        }

        public static async Task<int> ExampleMethodAsync()
        {
            var httpClient = new HttpClient();
            int exampleInt = (await httpClient.GetStringAsync("http://www.baidu.com")).Length;
            Console.WriteLine("Preparing to finish ExampleMethodAsync.");
            // After the following return statement, any method that's awaiting  
            // ExampleMethodAsync (in this case, StartButton_Click) can get the   
            // integer result.  
            return exampleInt;
        }

        static async void fun1()
        {
            Console.WriteLine("1");
            await ExampleMethodAsync();
            Console.WriteLine("2");
        }
    }
}

输出结果:

 

结论:

从输出可以看出,主线程碰到await时会立即返回,继续以非阻塞形式执行主线程下面的逻辑。

当await耗时操作完成时,继续执行await下面的逻辑(Console.WriteLine("2"))。

 

用法:

async方法里要用await!

如果 async 关键字修改的方法不包含 await 表达式或语句,则该方法将同步执行。 编译器警告将通知你不包含 await 语句的任何异步方法,因为该情况可能表示存在错误。

await一般配合Task.Run()使用,例如:

        static async void fun3()
        {
            await Task.Run(() => { Console.WriteLine("A"); }).ConfigureAwait(false);
        }

 

通过使用 ConfigureAwait,可以实现少量并行性: 某些异步代码可以与 GUI 线程并行运行,而不是不断塞入零碎的工作。

除了性能之外,ConfigureAwait 还具有另一个重要方面: 它可以避免死锁。 再次考虑图 3;如果向 DelayAsync 中的代码行添加“ConfigureAwait(false)”,则可避免死锁。 此时,当等待完成时,它会尝试在线程池上下文中执行 async 方法的剩余部分。 该方法能够完成,并完成其返回任务,因此不存在死锁。 如果需要逐渐将应用程序从同步转换为异步,则此方法会特别有用。

如果可以在方法中的某处使用 ConfigureAwait,则建议对该方法中此后的每个 await 都使用它。 前面曾提到,如果等待未完成的 Task,则会捕获上下文;如果 Task 已完成,则不会捕获上下文。 在不同硬件和网络情况下,某些任务的完成速度可能比预期速度更快,需要谨慎处理在等待之前完成的返回任务。

posted @ 2017-10-18 15:47  花生打代码会头痛  阅读(266)  评论(0)    收藏  举报