C#Async,await异步简单介绍

2021-06-10 05:06

阅读:647

标签:task   fse   pac   can   ext   ken   eth   ring   contain   

C# 5.0 引入了async/await,.net framework4.5开始支持该用法

使用:

由async标识的方法必须带有await,如果不带await,方法将被同步执行

        static void Main(string[] args)
        {
            fun22();
            Console.WriteLine($"Main await ThreadId {Thread.CurrentThread.ManagedThreadId}");
            Console.ReadKey();
        }

        private async static void fun22()
        {
            //sync同步(相对于调用函数的线程)
            Console.WriteLine($"pre await ThreadId {Thread.CurrentThread.ManagedThreadId}");
            await HelloWorld();
            //async异步(相对于调用函数的线程)
            Console.WriteLine($"after await ThreadId {Thread.CurrentThread.ManagedThreadId}");
        }

        private static Task HelloWorld()
        {
            //sync同步(相对于调用函数的线程)
            Console.WriteLine($"pre Task ThreadId {Thread.CurrentThread.ManagedThreadId}");

            //async异步(相对于调用函数的线程)
            return Task.Factory.StartNew(() =>
            {
          Thread.Sleep(1000); Console.WriteLine($"Task ThreadId {Thread.CurrentThread.ManagedThreadId}"); }); }

运行结果:

技术图片

结果说明:

只有执行到Task异步的时候,才使真正的异步 

 

微软的例子:

using System;
using System.IO;

namespace ConsoleApplication
{
    class Program
    {
        static async Task Main()
        {
            await ReadCharacters();
        }

        static async Task ReadCharacters()
        {
            String result;
            using (StreamReader reader = File.OpenText("existingfile.txt"))
            {
                Console.WriteLine("Opened file.");
                result = await reader.ReadToEndAsync();
                Console.WriteLine("Contains: " + result);
            }
        }
    }
}

  查看ReadToEndAsync源码,发现最后是TaskFactory.FromAsyncTrim,真正的异步由这个函数执行,也就是真正的异步是由Task的线程池执行的。

        [HostProtection(ExternalThreading = true)]
        [ComVisible(false)]
        public Task ReadAsync(Byte[] buffer, int offset, int count)
        {
            return ReadAsync(buffer, offset, count, CancellationToken.None);
        }
 
        [HostProtection(ExternalThreading = true)]
        [ComVisible(false)]
        public virtual Task ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            // If cancellation was requested, bail early with an already completed task.
            // Otherwise, return a task that represents the Begin/End methods.
            return cancellationToken.IsCancellationRequested
                        ? Task.FromCancellation(cancellationToken)
                        : BeginEndReadAsync(buffer, offset, count);
        }
 
        private Task BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
        {            
            return TaskFactory.FromAsyncTrim(
                        this, new ReadWriteParameters { Buffer = buffer, Offset = offset, Count = count },
                        (stream, args, callback, state) => stream.BeginRead(args.Buffer, args.Offset, args.Count, callback, state), // cached by compiler
                        (stream, asyncResult) => stream.EndRead(asyncResult)); // cached by compiler
        }

  

  

 

C#Async,await异步简单介绍

标签:task   fse   pac   can   ext   ken   eth   ring   contain   

原文地址:https://www.cnblogs.com/yaosj/p/10623081.html


评论


亲,登录后才可以留言!