11-C#.Net-多线程-Async-Await篇-学习笔记

C#中的async和await的使用详解 C#中的async和await的使用 在C#中,在很多的时候,都需要一些异步操作,并且在做完这些异步操作之后,可以在后面接着做一些处理,在 .net framework 4.5之后,便加入了一种简洁的方式来使用异步操作,这就是async和await。 async用来声明一个函数体,将其声明为异步方法,而await则是用在这个函数体的内部,用于等待一个异步操作的完成。 异步方法内部可以出现一个或者多个await,一般不要是0个,这样就失去了异步方法的意义了。 ... 阅读详情

一、async/await 基础

1.1 什么是async/await

定义

  • C# 5.0 (.NET 4.5) 引入的语法糖
  • C# 7.1 开始,Main入口也可以使用
  • C# 8.0 支持异步流(await foreach)和异步释放(await using)

什么是语法糖

  • 由编译器提供的便捷功能
  • 底层实现不变,但写代码更简洁
  • 类似的语法糖:var、表达式树、属性的get/set、字符串插值$""

1.2 基本用法

规则

// 1. async单独使用会警告,没有实际作用
public async void Method1() // 警告
{
    Console.WriteLine("没有await");
}

// 2. await必须在async方法内使用
public void Method2()
{
    await Task.Delay(1000); // 编译错误
}

// 3. async + await 配套使用
public async Task Method3()
{
    await Task.Delay(1000); // 正确
}

返回值规则

// 无返回值:返回Task(推荐)或void
public async Task NoReturnAsync()
{
    await Task.Delay(1000);
    // 默认返回Task
}

public async void NoReturnVoid()
{
    await Task.Delay(1000);
    // 不推荐,无法await或Wait
}

// 有返回值:返回Task<T>
public async Task<int> GetValueAsync()
{
    await Task.Delay(1000);
    return 123; // 实际返回Task<int>
}

为什么推荐Task而不是void

  • Task可以使用await、Wait、WhenAny、WhenAll等方法组合
  • void无法组合使用
  • Task可以捕获异常,void不行

二、async/await的核心价值

2.1 解决的问题

问题:既要有顺序,又要不阻塞

// 同步方法:有顺序,但阻塞
public void SyncMethod()
{
    Console.WriteLine("步骤1");
    Thread.Sleep(1000); // 阻塞
    Console.WriteLine("步骤2");
    Thread.Sleep(1000); // 阻塞
    Console.WriteLine("步骤3");
}

// 多线程:不阻塞,但无顺序
public void TaskMethod()
{
    Task.Run(() =>
    {
        Console.WriteLine("步骤1");
        Thread.Sleep(1000);
    });
    Task.Run(() =>
    {
        Console.WriteLine("步骤2");
        Thread.Sleep(1000);
    });
    Task.Run(() =>
    {
        Console.WriteLine("步骤3");
        Thread.Sleep(1000);
    });
    // 输出顺序不确定
}

// async/await:有顺序,不阻塞
public async Task AsyncMethod()
{
    await Task.Run(() =>
    {
        Console.WriteLine("步骤1");
        Thread.Sleep(1000);
    });
    await Task.Run(() =>
    {
        Console.WriteLine("步骤2");
        Thread.Sleep(1000);
    });
    await Task.Run(() =>
    {
        Console.WriteLine("步骤3");
        Thread.Sleep(1000);
    });
    // 按顺序输出:步骤1 -> 步骤2 -> 步骤3
}

2.2 核心理念

以同步编程的方式来写异步代码

  • 代码看起来像同步,实际是异步执行
  • 降低编程难度
  • 保持代码可读性

三、await的执行机制

3.1 执行流程

public async Task TestAsync()
{
    Console.WriteLine($"主线程ID: {Thread.CurrentThread.ManagedThreadId}");
    
    // 1. 遇到await,主线程立即返回(不阻塞)
    await Task.Run(() =>
    {
        Console.WriteLine($"子线程ID: {Thread.CurrentThread.ManagedThreadId}");
        Thread.Sleep(3000);
        Console.WriteLine("子线程完成");
    });
    
    // 2. await后的代码,由线程池的线程执行
    Console.WriteLine($"await后线程ID: {Thread.CurrentThread.ManagedThreadId}");
    Console.WriteLine("继续执行");
}

关键点

  1. 主线程遇到 await 就返回,不等待(非阻塞)
  2. await 后的代码会在 Task 完成后继续执行
  3. await 后的代码可能由子线程、主线程或其他线程执行

一个典型的执行顺序示例,能直观说明 await 的非阻塞特性:

public static void Show()
{
    Console.WriteLine($"start  线程ID: {Thread.CurrentThread.ManagedThreadId}"); // ① 主线程
    Async();  // 调用异步方法
    Console.WriteLine($"aaa    线程ID: {Thread.CurrentThread.ManagedThreadId}"); // ③ 主线程继续,不等待
}

public static async void Async()
{
    Console.WriteLine($"ddd    线程ID: {Thread.CurrentThread.ManagedThreadId}"); // ② 还是主线程
    await Task.Run(() =>
    {
        Thread.Sleep(500);
        Console.WriteLine($"bbb    线程ID: {Thread.CurrentThread.ManagedThreadId}"); // ④ 子线程
    });
    Console.WriteLine($"ccc    线程ID: {Thread.CurrentThread.ManagedThreadId}"); // ⑤ await后,线程池线程
}

实际输出顺序:start → ddd → aaa → bbb → ccc

⚠️ 注意 aaa 在 bbb 之前输出——主线程遇到 await 后立即返回继续执行,子线程的工作和主线程是并发的。

3.2 与ContinueWith的对比

async/await 出现之前,控制多个异步操作的顺序只能靠 ContinueWith 链式回调,代码可读性很差:

// 老写法:ContinueWith 链式调用控制顺序,嵌套深、难维护
Task<int> task = taskFactory.StartNew<int>(() =>
{
    Thread.Sleep(3000);
    return 123;
}).ContinueWith(c =>
{
    Thread.Sleep(3000);
    return 234;
}).ContinueWith(t =>
{
    Thread.Sleep(3000);
    return 345;
});

用 await 改写后,代码结构和同步方法一样直观:

// 新写法:await 顺序执行,清晰易读
public async Task UseAwait()
{
    await Task.Run(() => { Thread.Sleep(3000); Console.WriteLine("步骤1"); });
    await Task.Run(() => { Thread.Sleep(3000); Console.WriteLine("步骤2"); });
    await Task.Run(() => { Thread.Sleep(3000); Console.WriteLine("步骤3"); });
}

await 的优势

  • 代码更简洁,可读性更好
  • 写法像同步代码,实际是异步执行
  • 自动处理异常传播,不需要手动在每个 ContinueWith 里 try-catch

四、带返回值的async方法

4.1 基本用法

public async Task<long> SumAsync()
{
    Console.WriteLine($"开始计算,线程ID: {Thread.CurrentThread.ManagedThreadId}");
    
    long result = 0;
    
    // 第一个计算
    await Task.Run(() =>
    {
        Console.WriteLine($"计算1,线程ID: {Thread.CurrentThread.ManagedThreadId}");
        for (long i = 0; i < 999_999_999; i++)
        {
            result += i;
        }
    });
    
    Console.WriteLine($"计算1完成,线程ID: {Thread.CurrentThread.ManagedThreadId}");
    
    // 第二个计算
    await Task.Run(() =>
    {
        Console.WriteLine($"计算2,线程ID: {Thread.CurrentThread.ManagedThreadId}");
        for (long i = 0; i < 999_999_999; i++)
        {
            result += i;
        }
    });
    
    Console.WriteLine($"计算2完成,线程ID: {Thread.CurrentThread.ManagedThreadId}");
    
    return result; // 自动包装成Task<long>
}

4.2 调用方式

// 方式1:await(推荐,不阻塞)
public async Task CallAsync()
{
    long result = await SumAsync();
    Console.WriteLine($"结果: {result}");
}

// 方式2:Result(不推荐,阻塞)
public void CallSync()
{
    long result = SumAsync().Result; // 阻塞,相当于同步
    Console.WriteLine($"结果: {result}");
}

// 方式3:Wait(不推荐,阻塞)
public void CallWait()
{
    Task<long> task = SumAsync();
    task.Wait(); // 阻塞
    long result = task.Result;
    Console.WriteLine($"结果: {result}");
}

注意

  • 访问Result或Wait会阻塞,失去async/await的意义
  • 推荐使用await,保持异步特性

五、async/await的底层实现

5.1 状态机

IL代码分析

// C#代码
public async Task SimpleMethod()
{
    await Task.Delay(1000);
    Console.WriteLine("完成");
}

// 编译后生成状态机(简化版)
private struct StateMachine
{
    public int state;
    public AsyncTaskMethodBuilder builder;
    
    public void MoveNext()
    {
        try
        {
            switch (state)
            {
                case 0:
                    // 执行await之前的代码
                    var awaiter = Task.Delay(1000).GetAwaiter();
                    if (!awaiter.IsCompleted)
                    {
                        state = 1;
                        // 等待完成
                        return;
                    }
                    goto case 1;
                    
                case 1:
                    // 执行await之后的代码
                    Console.WriteLine("完成");
                    state = -2;
                    break;
            }
        }
        catch (Exception ex)
        {
            state = -2;
            builder.SetException(ex);
        }
        
        builder.SetResult();
    }
}

状态机执行流程

  1. 实例化状态机
  2. 将状态机交给builder执行
  3. 整理线程上下文
  4. 调用MoveNext()方法
  5. 根据状态执行不同分支
  6. 异常时状态重置为-2
  7. 完成时调用SetResult()

5.2 状态机的价值

类比:红绿灯

  • 红灯:停止
  • 绿灯:行驶
  • 黄灯:减速

状态机

  • 一个对象在不同状态下执行不同行为
  • await将方法分割成多个状态
  • 每个状态对应一个await

六、性能对比

6.1 文件读取对比

// 1. Async版本(推荐)
private async Task<byte[]> ReadAsync(string path)
{
    Console.WriteLine($"ReadAsync开始,线程ID: {Thread.CurrentThread.ManagedThreadId}");
    
    var result = await File.ReadAllBytesAsync(path);
    // 读取文件时,没有开启新线程
    // 主线程告诉系统要做什么,然后就返回了
    // 降低了线程开启数量,降低了CPU负荷
    
    Console.WriteLine($"ReadAsync结束,线程ID: {Thread.CurrentThread.ManagedThreadId}");
    return result;
}

// 2. Task版本
private Task<byte[]> ReadTask(string path)
{
    Console.WriteLine($"ReadTask开始,线程ID: {Thread.CurrentThread.ManagedThreadId}");
    
    var result = Task.Run(() =>
    {
        Console.WriteLine($"ReadTask执行,线程ID: {Thread.CurrentThread.ManagedThreadId}");
        return File.ReadAllBytes(path);
    });
    // 铁定开启新线程
    
    Console.WriteLine($"ReadTask结束,线程ID: {Thread.CurrentThread.ManagedThreadId}");
    return result;
}

// 3. Sync版本
private byte[] ReadSync(string path)
{
    Console.WriteLine($"ReadSync开始,线程ID: {Thread.CurrentThread.ManagedThreadId}");
    var result = File.ReadAllBytes(path);
    Console.WriteLine($"ReadSync结束,线程ID: {Thread.CurrentThread.ManagedThreadId}");
    return result;
}

性能测试结果

20次读取大文件:
- Async: 约3000ms
- Task:  约3500ms
- Sync:  约6000ms

6.2 Web请求对比

// 1. Async版本(推荐)
private async Task<string> WebAsync(string url)
{
    HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
    
    // 使用异步版本的API
    using (HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse)
    {
        StreamReader sr = new StreamReader(response.GetResponseStream());
        return await sr.ReadToEndAsync(); // 异步读取
    }
}

// 2. Task版本
private Task<string> WebTask(string url)
{
    return Task.Run(() =>
    {
        return InvokeWebRequest(url); // 同步方法包装
    });
}

// 3. Sync版本
private string WebSync(string url)
{
    return InvokeWebRequest(url);
}

性能测试结果

10次Web请求(每次5秒):
- Async: 约5秒(并发)
- Task:  约5秒(并发)
- Sync:  约50秒(串行)

6.3 CPU密集型计算对比

// 1. Async版本
private async Task<long> CalculationAsync(long total)
{
    return await Task.Run(() =>
    {
        long result = 0;
        for (long i = 0; i < total; i++)
        {
            result += i;
        }
        return result;
    });
}

// 2. Task版本
private Task<long> CalculationTask(long total)
{
    return Task.Run(() =>
    {
        long result = 0;
        for (long i = 0; i < total; i++)
        {
            result += i;
        }
        return result;
    });
}

// 3. Sync版本
private long CalculationSync(long total)
{
    long result = 0;
    for (long i = 0; i < total; i++)
    {
        result += i;
    }
    return result;
}

性能测试结果

10次计算(每次10亿次循环):
- Task:  约8秒
- Async: 约8秒
- Sync:  约80秒

结论

  • CPU密集型:Async和Task性能相同,都需要开启线程
  • IO密集型:Async性能更好,不需要额外线程

七、适用场景

7.1 适合使用async/await的场景

1. IO密集型操作(推荐)

// 文件操作
await File.ReadAllBytesAsync(path);
await File.WriteAllTextAsync(path, content);

// 数据库操作
await connection.OpenAsync();
await command.ExecuteNonQueryAsync();

// Web请求
await httpClient.GetStringAsync(url);

// Redis操作
await redis.StringGetAsync(key);

2. 与第三方交互(非托管资源)

  • 数据库查询
  • Redis缓存
  • Web API调用
  • 文件读写

7.2 不适合使用async/await的场景

1. CPU密集型计算(不推荐)

// 不推荐:async/await对CPU密集型无优势
public async Task<long> CalculateAsync()
{
    return await Task.Run(() =>
    {
        // 大量计算
        long result = 0;
        for (long i = 0; i < 1_000_000_000; i++)
        {
            result += i;
        }
        return result;
    });
}

// 推荐:直接使用Task
public Task<long> CalculateTask()
{
    return Task.Run(() =>
    {
        long result = 0;
        for (long i = 0; i < 1_000_000_000; i++)
        {
            result += i;
        }
        return result;
    });
}

2. 本地计算(托管资源)

  • 内存中的数据处理
  • 算法计算
  • 数据转换

八、不同框架中的应用

8.1 ASP.NET Core(推荐使用)

[HttpGet]
public async Task<IActionResult> GetDataAsync()
{
    var data = await _service.GetDataAsync();
    return Ok(data);
}

优势

  • 不阻塞线程池线程
  • 提高服务器并发能力
  • 可以处理更多请求

8.2 控制台应用(可以使用)

// C# 7.1+
static async Task Main(string[] args)
{
    await DoWorkAsync();
}

8.3 WinForms(需要注意)

private async void btnClick_Click(object sender, EventArgs e)
{
    // 不阻塞UI线程
    var result = await GetDataAsync();
    
    // await后的代码在UI线程执行,可以直接更新UI
    lblResult.Text = result;
}

注意事项

  • 事件处理器可以使用async void
  • await后的代码会回到UI线程
  • 可以直接更新UI控件

8.4 WPF(类似WinForms)

private async void Button_Click(object sender, RoutedEventArgs e)
{
    var result = await GetDataAsync();
    TextBlock.Text = result;
}

九、C# 8.0 新特性

9.1 异步流(await foreach)

// 生成异步序列
public async IAsyncEnumerable<int> GenerateSequence()
{
    for (int i = 0; i < 20; i++)
    {
        await Task.Delay(100);
        yield return i;
    }
}

// 消费异步序列
private async Task ConsumeAsync()
{
    await foreach (var i in GenerateSequence())
    {
        Console.WriteLine($"接收到: {i}");
    }
}

9.2 异步释放(await using)

await using (var resource = new AsyncDisposableResource())
{
    // 使用资源
}
// 自动调用DisposeAsync()

十、最佳实践

10.1 命名规范

// 异步方法以Async结尾
public async Task<string> GetDataAsync()
{
    return await _repository.QueryAsync();
}

10.2 避免async void

// 错误:无法捕获异常,无法await
public async void BadMethodAsync()
{
    await Task.Delay(1000);
}

// 正确:返回Task
public async Task GoodMethodAsync()
{
    await Task.Delay(1000);
}

// 例外:事件处理器可以使用async void
private async void Button_Click(object sender, EventArgs e)
{
    await DoWorkAsync();
}

10.3 避免阻塞

// 错误:阻塞
var result = GetDataAsync().Result;

// 错误:阻塞
GetDataAsync().Wait();

// 正确:异步等待
var result = await GetDataAsync();

10.4 ConfigureAwait

// 库代码中使用,避免捕获上下文
var result = await GetDataAsync().ConfigureAwait(false);

// UI代码中不使用,需要回到UI线程
var result = await GetDataAsync();

十一、小结

  • async/await 是语法糖:底层是状态机实现
  • 核心价值:以同步方式写异步,降低编程难度
  • 适用场景:IO 密集型操作(文件、网络、数据库)
  • 不适用场景:CPU 密集型计算
  • 性能提升:提高吞吐量,不是降低单个请求时间
  • 避免阻塞:不要使用 Result 或 Wait
  • 命名规范:异步方法以 Async 结尾
  • 返回类型:优先使用 Task,避免 void
C# 异步之Async/await 该文章仅为个人理解,如有错误请指正,标红内容为重点,会有针对异步的多个文章,包含Task,APM(BeginInvoke,EndInvoke)等。 一、基本概念: Async/await 关键字是在.Net 4.5引入的关键字来创建自动延续任务实现异步调用。 async/await是语法糖,等价于task.Run().ContinueWith(action,Task.FromCurrentS... 阅读详情

相关推荐

C#中await/async用法

看微软的官方文档看的头大,比较晦涩的,反正我是啃不动,这里通俗的解释一下c# 中的await/async说白了await/async就是一个语法糖,单纯使用await/async并不会创建一个线程,创建线程的这个操作由是线程池决定的。那么我们为啥还要使用await/async呢?答:为了更好的编写异步操作,也就是识别性更高 可以看到,单纯在方...

进击的豌豆的博客 2912

C# async / await 用法

await 运算符暂停对其所属的 async 方法的求值,直到其操作数表示的异步操作完成。异步操作完成后,await 运算符将返回操作的结果(如果有)。当 await 运算符应用到表示已完成操作的操作数时,它将立即返回操作的结果,而不会暂停其所属的方法。await 运算符不会阻止计算异步方法的线程。当 await 运算符暂停其所属的异步方法时,控件将返回到方法的调用方。下面来做一个演示,点击按钮1开始启动异步,点击按钮2,就返回结果,如果不点击按钮2,那么异步一直在循环中。

熊思雨的博客 2万+

C# async/await不是语法糖:异步编程底层原理与实战避坑

async/await是现代C#异步编程的核心机制,本质是编译器驱动的状态机契约,而非简化写法的语法糖。它通过解耦等待操作与线程绑定,实现I/O密集型任务的零线程挂起,显著降低上下文切换与内存开销。其技术价值在于统一抽象异步操作(如HTTP请求、串口读取、文件IO),支撑高并发上位机系统、无线温度监测等典型工业场景。结合Task状态机、SynchronizationContext捕获、ConfigureAwait控制执行上下文等关键能力,开发者可构建响应式、可伸缩且易维护的异步应用。本文深入剖析async/

weixin_34146805的博客 320

C#异步编程(async和await)

异步编程的核心是Task和Task对象,这两个对象对异步操作建模。它们受关键字async和await的支持。在大多数情况下模型十分简单:对于 I/O 绑定代码,等待一个在async方法中返回Task或Task的操作。对于 CPU 绑定代码,等待一个使用Task.Run方法在后台线程启动的操作。通过使用异步编程,可以避免性能瓶颈并增强应用程序的总体响应能力。但是,编写异步应用程序的传统技术可能比较复杂,使它们难以编写、调试和维护。C# 5 引入了一种简便方法,即异步编程。

风清扬的专栏 8741

顶刊《会计研究》数据复现|最新上市公司数智化数据

本文基于Python文本分析方法构建了中国A股上市公司数智化指标(1991-2024),通过识别年报中的"机器学习""智能医疗"等关键词,量化企业数字化与智能化融合程度。研究发现数智化企业更倾向于非正式渠道的定性披露以规避风险,该指标为监管完善信披规则提供了参考。研究还揭示了数智化对企业信息披露策略的转变,并提出了未来研究方向,包括数智化对绿色创新、ESG表现等影响机制。数据覆盖非金融类上市公司,采用文本挖掘技术构建结构化指标,为相关领域研究提供了微观基础。

PPdata_Academy的博客 1467

使用 Java + PaddleOCR 实现表格识别,支持导出 HTML 和 Excel(附源码)

使用Java+PaddleOCR快速搭建表格识别系统,无需处理底层模型细节。系统支持表格结构识别和内容识别,可将图片转换为可编辑表格格式。文章提供了完整的实现流程,包括Maven依赖引入、模型下载(包含检测、识别、分类和表格结构模型)及参数配置说明。SmartJavaAI支持多种高性能模型选择,适用于不同应用场景,帮助开发者快速实现表格识别功能。

deng775747758的博客 1473

C# 多线程之 async/await

引言 1 async/await 是 .NetFramework 4.5 版本 中的功能 2 async/await 是C# 保留 关键字,通常成对出现 3 async修饰方法,放在方法类型前面,可以单独出现,但是单独出现和普通方法功能一样,而且还有警告 4 await 在方法体中,只能出现在 task 或 async 方法前面,单独出现会报错 async/await执行顺序 1 在async修饰的方法中,遇到await关键字,即返回到主方法执行后面的逻辑。 2 当被await修饰的任务执行完毕后,再执行a

weixin_40719943的博客 1001

基准电压 + 运放 + 低边MOS恒流源控制原理

因为恒流源强制 Iout不变,而 Vin​ 增加时,负载压降 Iout⋅Rload不变,多余的电压只能由MOS管的 VDS承担,因此 VDS必然增加。在饱和区,MOS 管的 ID 仅由 VGS决定,与 VDS 无关,这样,负载变化时,VDS可自由调整以维持 Iout恒定。当 Vin​ 小到无法满足 VDS>VGS−Vth时,MOS管进入线性区,Iout 会随 Vin​ 下降而减小,恒流失效。由于 Vref和 Rsense未变,Iout无需调整,运放无需动作,OUT保持不变,Iout恒定。

weixin_50643237的博客 2651

C# Task中的Func, Action, Async与Await的使用

C# Task中的Func, Action, Async与Await的使用 在说Asnc和Await之前,先说明一下Func和Action委托, Task任务的基础的用法 1. Func Func是一种委托,这是在3.5里面新增的,2.0里面我们使用委托是用Del...

baihuomeng2210的博客 586

SOC Boot学习(二)——JTAG Debug介绍

JTAG(Joint Test Action Group ,联合测试行动小组 ) 是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真、调试。JTAG 技术是一种嵌入式调试技术,它在芯片内部封装了专门的测试电路 TAP ( Test Access Port ,测试访问口),通过专用的 JTAG 测试工具对内部节点进行测试。如今大多数比较复杂的器件都支持 JTAG 协议,如 ARM 、 DSP 、 FPGA 器件等。

yttt的博客 1605

用Arduino和MAX30102做个心率血氧仪,从硬件连线到算法调试全流程避坑

本文详细介绍了如何使用Arduino和MAX30102传感器构建高精度心率血氧仪,涵盖硬件连线、软件配置、信号处理及算法优化全流程。通过实战案例和避坑指南,帮助开发者快速实现临床级精度的健康监测设备,适用于可穿戴设备和医疗健康领域。

weixin_26897585的博客 383

Async和Await异步编程的原理

1. 简介从4.0版本开始.NET引入并行编程库,用户能够通过这个库快捷的开发并行计算和并行任务处理的程序。在4.5版本中.NET又引入了Async和Await两个新的关键字,在语言层面...

dotNET跨平台 1019

BDD测试用例:Playwright的MCP Server实战

Playwright MCP Server建立了大模型和真实的浏览环境之间的桥梁,可以让大模型操作多款浏览器完成测试任务。

Criss@陈磊 438

C#开发常见面试题二(多线程)

当一个方法中包含yield return时,这个方法必须返回一个实现了IEnumerable、IEnumerator或IAsyncEnumerable的类型(取决于是否使用异步迭代器).NET Framework 中名字以Async结尾的方法,例如WebClient上的方法,和大部分BeginXXX方法(异步编程模型模式,APM)/Mutex(互斥体)异步方法的返回值一般是Task,T是真正的返回值类型,Task。如果一个方法是异步方法,那么一般在调用这个方法的时候在方法前加await关键字;

yannsann的博客 4359

触摸芯片RM1015B基本使用方法

RM1015B触摸芯片使用指南:该芯片采用4通道设计(实际使用3通道),通过I2C接口通信(设备地址0x2B)。硬件设计需注意中断/复位引脚复用,需上拉处理。软件配置包括初始化、中断处理和定时器扫描,通过设置各通道阈值(0-300W)调节灵敏度,值越小越灵敏。调试时可调用rm1015B_debug_func()输出波形数据。典型应用场景包括接近检测和手势识别,中断触发后需在8ms内响应。特别注意不同通道的寄存器映射关系及校准流程,确保检测准确性。

云淡风轻 176

【高级强化学习:算法、优化与泛化】第13章 扩散模型策略优化(Diffusion Policy Optimization)

\quad$ 计算均值 $\mu_t = \frac{1}{\sqrt{\alpha_t}} \left( x_t - \frac{1 - \alpha_t}{\sqrt{1 - \bar{\alpha}_t}} \tilde{\epsilon} \right)$.$\quad$ 组合得分估计: $\tilde{\epsilon} = \epsilon_{\text{unc}} + w \cdot (\epsilon_{\text{con}} - \epsilon_{\text{unc}})$.

u012133341的博客 336

C#的async和await

1 例子1: 2 3 public class MyClass 4 { 5 public MyClass() 6 { 7 DisplayValue(); //这里不会阻塞 8 System.Diagnostics.Debug.WriteLine("MyClass() End."); ...

b663455888378594的博客 139

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

理解 C# 中的 async await

转自:xiaoxiaotankcnblogs.com/xiaoxiaotank/p/14303803.html前言一个老掉牙的话题,园子里的相关优秀文章已经有很多了,我写这篇文章完全是想以自己的思维方式来谈一谈自己的理解。(PS:文中涉及到了大量反编译源码,需要静下心来细细品味)一、从简单开始为了更容易理解这个问题,我们举一个简单的例子:用异步的方式在控制台上分两步输出"Hello World!"...

weixin_68436326的博客 546

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

.net 中的async,await理解

理解: 1、async修饰的方法可理解为异步方法(必须要配合await,否则和普通方法无异)2、当async方法执行遇到await,则立即将控制权转移到async方法的调用者3、由调用者决定是否需要等待async方法执行完再继续往下执行4、await会挂起当前方法,即阻塞当前方法继续往下执行,转交控制权给调用者 注意:如果调用一个async方 法,却不使用await关键字来标记一个挂起点的话,...

weixin_30478619的博客 279

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【转】异步编程系列(Thread、Task、async/await、ajax等)

序 经过一番努力,我写的异步编程系列也算有头有尾,当然不是说这个系列已经更新完毕,这个头尾只是表示新旧知识点都有简单涉及到,接下去我还会丰富这一系列并且有机会整个小应用(愿景是弄一个开源组件吧,结合socket)。 术语: APM    异步编程模型,Asynchronous Programming Model EAP    基于事件的异步编程模式,Event-based Asynchronous Pattern TAP    基于任务的异步编程模式,Task-based As...

sinolover的专栏 618

async await

随着 Node 7 的发布,越来越多的人开始研究据说是异步编程终级解决方案的 async/await。我第一次看到这组关键字并不是在 JavaScript 语言里,而是在 c# 5.0 的语法中。C# 的 async/await 需要在 .NET Framework 4.5 以上的版本中使用,因此我还很悲伤了一阵——为了要兼容 XP 系统,我们开发的软件不能使用高于 4.0 版本的 .NET Fr...

风华绝代的博客 2006

async 与 await 在 Web 下的应用

仔细看完老赵的《C#与Visual Basic的未来》大家应该都能明白这两个关键字的作用是什么了。

CLnFHY9fQ的博客 260

.NET 11 Runtime Async 详解

.NET 11引入的RuntimeAsync通过将异步控制流延迟至JIT阶段处理,摒弃传统async/await的编译时状态机生成,实现“按需付费”的异步模型。它采用新的AsyncCallingConvention,利用寄存器传递返回值与Continuation,使无暂停调用链性能接近同步代码,提升近20倍;即使发生暂停,也显著降低开销,减少内存分配,支持跨方法优化与内联。相比GreenThread,其轻量级Continuation仅需数十字节,避免调度与硬件兼容问题。

sheep404的博客 128

C#:多线程与异步

多线程 介绍: 多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多余一个线程,进而提升整体处理性能。--来自百度百科 分类: 原生线程: 托管线程: .........

子昊 3647
上一篇: 10-C#.Net-多线程-进阶篇-学习笔记
下一篇: 12-C#.Net-加密解密-学习笔记
似水明俊德
博客等级 码龄8年 247粉丝 276原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值