.net core 非阻塞的异步编程 及 线程调度过程

简介: 【11月更文挑战第12天】本文介绍了.NET Core中的非阻塞异步编程,包括其基本概念、实现方式及应用示例。通过`async`和`await`关键字,程序可在等待I/O操作时保持线程不被阻塞,提高性能。文章还详细说明了异步方法的基础示例、线程调度过程、延续任务机制、同步上下文的作用以及如何使用`Task.WhenAll`和`Task.WhenAny`处理多个异步任务的并发执行。
  1. 非阻塞异步编程概述
  • 在.NET Core 中,非阻塞异步编程是一种高效的编程模式,它允许程序在等待某些操作(如 I/O 操作,像读取文件、网络请求等)完成时不会阻塞线程,从而可以充分利用系统资源,提高应用程序的性能和响应能力。
  • 主要通过asyncawait关键字来实现。async用于标记一个方法是异步方法,await用于暂停异步方法的执行,直到等待的操作完成。
  1. 异步方法基础示例
  • 以下是一个简单的异步方法示例,用于模拟一个异步操作(比如读取文件或网络请求):


using System;
using System.Threading.Tasks;
class Program
{
    static async Task Main()
    {
        Console.WriteLine("Before asynchronous operation");
        await DoSomethingAsync();
        Console.WriteLine("After asynchronous operation");
    }
    static async Task DoSomethingAsync()
    {
        await Task.Delay(1000); // 模拟一个耗时1秒的操作
    }
}


  • 在这个示例中:
  • Main方法被标记为async,表示它是一个异步方法。
  • await DoSomethingAsync()暂停Main方法的执行,直到DoSomethingAsync中的Task.Delay操作完成。
  • DoSomethingAsync方法也是异步的,它通过await Task.Delay(1000)模拟一个耗时 1 秒的操作。


  1. 线程调度过程 - 任务和线程池的关系
  • 当一个异步方法被调用时,它通常会返回一个TaskTask<T>(其中T是返回值类型)。这些任务会被放入线程池(ThreadPool)中进行调度。
  • 线程池是一组预先创建好的线程,用于执行任务。当一个await操作发生时,当前线程可能会被释放回线程池,去执行其他任务。
  • 例如,在上面的DoSomethingAsync方法中,当执行到await Task.Delay(1000)时,当前执行的线程可以去处理其他任务。当Task.Delay完成后,线程池会调度一个线程(可能是之前的线程,也可能是其他线程)来继续执行DoSomethingAsync方法的后续代码。
  1. 继续执行的机制 - 延续任务(Continuation)
  • 当一个await操作完成后,后续的代码会作为一个延续任务被安排执行。延续任务是一种特殊的任务,它依赖于之前的任务完成。
  • 例如,在Main方法中,await DoSomethingAsync()后的Console.WriteLine("After asynchronous operation");就是一个延续任务。当DoSomethingAsync中的操作完成后,线程池会调度一个线程来执行这个延续任务。
  • 这种机制确保了异步操作完成后的正确执行顺序,同时避免了不必要的线程阻塞。
  1. 异步编程中的同步上下文(Synchronization Context)
  • 在某些情况下,如在 Windows Forms 或ASP.NET应用程序中,存在同步上下文。同步上下文用于确保在正确的线程上执行代码,以避免线程安全问题。
  • 例如,在 Windows Forms 应用程序中,UI 控件只能在创建它们的线程(通常是 UI 线程)上进行更新。当在异步方法中更新 UI 时,await操作会捕获当前的同步上下文,并在合适的线程(如 UI 线程)上执行延续任务。
  • 不过,在控制台应用程序(如前面的示例)中,通常没有同步上下文,所以延续任务可以在任何线程池线程上执行。
  1. 复杂场景下的线程调度 - 多个异步任务并发执行
  • 可以使用Task.WhenAllTask.WhenAny来处理多个异步任务的并发执行。
  • Task.WhenAll会等待所有指定的任务都完成,例如:


static async Task Main()
{
    var task1 = DoSomethingAsync();
    var task2 = DoSomethingElseAsync();
    await Task.WhenAll(task1, task2);
    Console.WriteLine("Both tasks are completed");
}


  • 在这个示例中,task1task2是两个异步任务,Task.WhenAll会使Main方法暂停执行,直到task1task2都完成。在等待过程中,线程池会有效地调度线程来执行这些任务,提高了并发性能。
  • Task.WhenAny则是等待其中一个任务完成,一旦有一个任务完成,就会继续执行后续代码。这在处理多个可能有不同响应时间的任务时非常有用,比如多个网络请求,只要有一个请求返回结果就可以进行下一步操作。
相关文章
|
6月前
|
Java Android开发 UED
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
【7月更文挑战第28天】在Android开发中,确保UI流畅性至关重要。多线程与异步编程技术可将耗时操作移至后台,避免阻塞主线程。我们通常采用`Thread`类、`Handler`与`Looper`、`AsyncTask`及`ExecutorService`等进行多线程编程。
66 2
|
5月前
|
数据库 开发者
.NET 异步编程之谜:async/await 模式究竟隐藏着怎样的神奇力量?
【8月更文挑战第28天】在当今注重效率和响应性的软件开发领域,.NET 的 async/await 模式如同得力助手,简化异步代码编写,使代码更易理解和维护。通过后台执行耗时操作,如网络请求和数据库查询,避免阻塞主线程,显著提升系统响应性。此模式不仅适用于网络请求,还广泛应用于数据库操作和文件读写。合理使用 async/await 可大幅优化性能,但需注意避免过度使用、正确处理调用链及异常,以确保系统稳定性和高效性。深入探索 async/await,助您构建更出色的应用程序。
63 0
|
5月前
|
算法 Unix Linux
linux线程调度策略
linux线程调度策略
110 0
|
3月前
|
监控 网络安全 调度
Quartz.Net整合NetCore3.1,部署到IIS服务器上后台定时Job不被调度的解决方案
解决Quartz.NET在.NET Core 3.1应用中部署到IIS服务器上不被调度的问题,通常需要综合考虑应用配置、IIS设置、日志分析等多个方面。采用上述策略,结合细致的测试和监控,可以有效地提高定时任务的稳定性和可靠性。在实施任何更改后,务必进行充分的测试,以验证问题是否得到解决,并监控生产环境的表现,确保长期稳定性。
171 1
|
3月前
|
安全 调度 C#
STA模型、同步上下文和多线程、异步调度
【10月更文挑战第19天】本文介绍了 STA 模型、同步上下文和多线程、异步调度的概念及其优缺点。STA 模型适用于单线程环境,确保资源访问的顺序性;同步上下文和多线程提高了程序的并发性和响应性,但增加了复杂性;异步调度提升了程序的响应性和资源利用率,但也带来了编程复杂性和错误处理的挑战。选择合适的模型需根据具体应用场景和需求进行权衡。
|
4月前
|
Java Android开发 UED
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
在Android开发中,为应对复杂应用场景和繁重计算任务,多线程与异步编程成为保证UI流畅性的关键。本文将介绍Android中的多线程基础,包括Thread、Handler、Looper、AsyncTask及ExecutorService等,并通过示例代码展示其实用性。AsyncTask适用于简单后台操作,而ExecutorService则能更好地管理复杂并发任务。合理运用这些技术,可显著提升应用性能和用户体验,避免内存泄漏和线程安全问题,确保UI更新顺畅。
157 5
|
4月前
|
存储 Java 数据处理
进程中的线程调度
进程是应用程序运行的基本单位,包括主线程、用户线程和守护线程。计算机由存储器和处理器协同操作,操作系统设计为分时和分任务模式。在个人PC普及后,基于用户的时间片异步任务操作系统确保了更好的体验和性能。线程作为进程的调度单元,通过覆写`Thread`类的`run`方法来处理任务数据,并由系统调度框架统一管理。微服务架构进一步将应用分解为多个子服务,在不同节点上执行,提高数据处理效率与容错性,特别是在大规模数据存储和处理中表现显著。例如,利用微服务框架可以优化算法,加速业务逻辑处理,并在不同区块间分配海量数据存储任务。
|
6月前
|
监控 安全 Java
Java中的线程调度与性能优化技巧
Java中的线程调度与性能优化技巧
|
6月前
|
Java Linux API
深入理解Java中的多线程调度策略
深入理解Java中的多线程调度策略
|
7月前
|
开发框架 监控 Java
【.NET Core】多线程之线程池(ThreadPool)详解(二)
【.NET Core】多线程之线程池(ThreadPool)详解(二)
113 3