VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > c#编程 >
  • C#异步编程

异步编程

async/await特性异步编程

  • 使用模型:
private await Task<int> YibuAsync(int a)//定义一个异步方法 YibuAsync await关键字指示编译器方法内部可能会存在await表达式
{
    //do something
    int b = await AnotherAsync(a);//如果只是标记了async关键字,但方法内没有await表达式,方法仍将同步执行
    return b;//b实际返回到了Task.Result中
}
Task<int> t = YibuAsync(10);//调用异步方法
//doing something

异步方法:async和await关键字同时存在。

  • 控制流程:
  1. 调用异步方法,调用后立即返回一个Task类型的对象。
  2. 调用异步方法后执行到await表达式后返回
  3. 继续执行调用者后续代码。
  4. 当需要使用异步方法执行结果时,若异步方法任未返回。将生成一个continue委托,当操作完成的时候调用continue委托。这个continue委托将控制权重新返回到”async”方法对应的await唤醒点处。
  • 异步方法返回类型
  1. void 调用并返回,调用异步方法后不再做任何处理
  2. Task
  3. Task<T>
  4. ValueTask<T>
  • await表达式
    await表达式由await关键字和一个空闲对象组成(任务),这个任务可以是Task类型的对象,也可以不是,默认情况下,这个任务在当前线程上异步执行。空闲对象指awaitable类型的实例。awaitable类型指包含GetAwaiter方法的类型,该方法没有参数,返回一个awaiter类型的对象。awaier类型包含以下成员:
    bool IsCompleted{get;}
    void OnCompleted(Action);
    以及一下成员之一:
    void GetResult();
    T GetResult();
  • Task.Run()方法
  1. Task.Run的方法签名及返回类型
    Run(Action action)    返回类型 Task
    Run(Action action,CancellationToken token) 返回类型 Task
    Run(Func<TResult> function)    返回类型 Task<TResult>
    Run(Func<TResult> functiom,CancellationToken token) 返回类型 Task<TResult>
    Run(Func<Task> function)  返回类型 Task
    Run(Func<Task> function,CancellationToken token) 返回类型 Task
    Run(Func<Task<TResult>> function) 返回类型 Task<TResult>
    Run(Func<Task<TResult>> function,CancellationToken token) 返回类型 Task<TResult>   

注:Action委托:无参无返回值;Func委托:无参有返回值。

BackgroundWorker类异步编程模式

使用BackgroundWorker类创建一个后台线程,并和主线程通信。该类主要成员如下:

属性:WorkerReportsProgress //设置后台线程是否把它的进度汇报给主线程。
WorkerSupportsCancellation //设置后台线程是否支持从主线程取消。
IsBusy //检查后台线程是否正在运行。
CancellationPending //检查后台线程是否需要被取消。
方法:RunWorkerAsync() //获取后台线程,并执行DoWork事件处理程序
CancelAsync() //把CancellationPending属性设置为True。DoWork事件处理程序需要检查这个属性来决定是否应该停止该处理。
RePortProgress()
事件:DoWork
ProgressChanged
RunWorkerCompleted
控制流程:实例化BackgroundWorker类,创建后台线程,设置后台线程是否向主线程汇报进度属性(WorkerReportsProgress)、后台线程是否支持从主线程取消属性(WorkerSupportsProgress)。在主线程调用RunWorkerAsync()方法,获取后台线程,并触发DOWork事件,执行Dowork事件处理程序,若要向主线程汇报进度,则DoWork事件处理程序调用ReportProgress()方法,触发ProgressChanged事件,主线程可以用附加到ProgressChanged事件上的处理程序。若要取消后台线程的执行,则在主线程中调用CancelSAsync()方法,该方法不会立即取消后台线程的执行,而是将CancellationPending的属性设置为True,后台线程的DoWork事件处理程序需要定期检查CancellationPending的属性,来判断是否需要退出。

任务并行库异步编程模式

Parallel.For循环与Parallel.Foreach循环:许多时候,在使用这两个结构时,每一次迭代都依赖于前一次迭代的计算或行为,但有时候不是,如果迭代之间彼此独立,并且程序运行在多处理机上,那么若能将不同的的迭代放在不同的处理器上进行的话,将受益匪浅。Parallel.For与Parallel.Foreach结构就是这样做的。

这两个结构的形式是包含输入参数的方法。Parallel.For方法有12个重载,其中最简单的签名如下:
public static ParallelLoopResult.For(int fromInclusive,int toExclusive,Action body);

  1. fromInclusive参数是迭代系列的第一个参数。
  2. ToExclusive参数是比迭代系列最后一个索引号大1的整数。即index<ToExclusive计算的一样。
  • 实例代码
    using System.Threading.Tasks;
    Parallel.For(0,15,i=>Console.WriteLine($"The square of {i} is {i*i}"));
    输出结果为无序的0到15的平方。

另一个并行循环结构是Parallel.Foreach(),该方法有多个重载,其中最简单的如下:
static ParallelLoopResult ForEach<TSource>(IEnumerable<TSource> source,Action<TSource> body)

  1. TSource 是集合中对象的类型。
  2. source 是Tsource对象的集合。
  3. body是要应用到集合中每一个元素上的Lambda表达式。

BeginInvoke与EndEInvoke异步编程模式

委托有两个方法:BeginInvoke与EndInvoke,当委托对象的方法列表中只有一个方法时,可使用这里两个方法使其在一个独立的线程中异步执行。分为三种模式,分别是等待直到完成模式、轮询模式和回掉模式。

先来介绍委托类型中的BeginInvoke与EndInvoke方法

  • BeginInvoke方法
  1. BeiginInvoke方法的参数组成:引用方法需要的参数、callback、state。
  2. BeginInvoke从线程池中获取一个线程,并让引用方法在新线程中开始运行。
  3. BeginInvoke方法返回给调用线程一个实现IAsyncResult接口的对象的引用,这个接口引用包含了在线程池中运行的异步方法的当前状态。
  4. 代码示例:
    IAsyncResult iar = del.BeginInvoke(a,b,null,null);
    a,b是委托方法的参数,del是对应的委托实例。
  • EndInvoke方法
    该方法获取由异步方法调用返回的值,并且释放线程使用的资源:
  1. 它接受一个由BeginInvoke方法返回的IAsyncResult对象的引用作为参数,并找到它关联的线程。
  2. 如果线程池中的线程已经退出,则其清理退出线程的状态并释放其资源,找到引用方法的返回值,并将它作为返回值返回。
  3. 如果当EndInvoke被调用时,线程池中的线程仍在运行,调用线程就会停止并等待其完成。
  4. 代码示例:
    int result = EndInvoke(iar);
    result是异步方法的返回值。
  • 等待直到完成模式
    在发起异步方法并做了一些其他处理后,就中断等待异步方法完成后再继续。
  • 轮询模式
    原始线程发起异步方法的调用,做一些其他的处理,并通过定期检查IAsyncResult的IsCompleted属性判断线程是否完成,如果完成,则调用EndInvoke方法,否则,做一些其他处理,间隔一段时间再检查。
  • 回调模式
    原始线程调用异步线程后不在管了,当异步方法调用结束后,系统在新线程中调用用户自定义的方法来处理结果,并且调用委托的EndInvoke方法。这个用户自定义的方法叫回掉方法。
 
原文:https://www.cnblogs.com/bgyl/p/15556354.html


相关教程