C#Async,await异步简单介绍

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

使用:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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(() =>
    {<br>          Thread.Sleep(1000);
        Console.WriteLine($"Task ThreadId {Thread.CurrentThread.ManagedThreadId}");
    });
}

运行结果:

结果说明:

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

 

微软的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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<Int32>.FromAsyncTrim,真正的异步由这个函数执行,也就是真正的异步是由Task的线程池执行的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public Task<int> ReadAsync(Byte[] buffer, int offset, int count)
{
    return ReadAsync(buffer, offset, count, CancellationToken.None);
}
 
[HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task<int> 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<int>(cancellationToken)
                : BeginEndReadAsync(buffer, offset, count);
}
 
private Task<Int32> BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
{           
    return TaskFactory<Int32>.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
}

  

  

 

posted @   翻白眼的哈士奇  阅读(935)  评论(1编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示