当前位置:   article > 正文

C#实现异步方式_c# 异步执行

c# 异步执行

在异步程序中,程序代码不需要严格按照编写时的顺序执行

为了改善代码性能,有时候需要在一个新的线程中运行一部分代码

有时候无需创建新的线程,但为了更好的利用单个线程的能力,需要改变代码的执行顺序

也就是说:

异步编程赋予代码非顺序执行的能力,让程序能够在部分耗时操作的同时,干其他的事情

一、通过委托实现异步

如果委托对象在调用列表中只有一个方法(引用方法),它就可以异步执行这个方法

委托类有 BeginInvoke,EndInvoke 方法,可以用以下方式使用:

  • 当调用 BeginInvoke 方法时,它开始在一个独立线程上执行引用方法,并立即返回到原始线程;原始线程可以继续运行,而引用方法会在线程池大的线程中并行执行
  • 当程序希望获取已完成的异步方法的结果时,可以检查 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 属性,或者调用 EndInvoke 方法等待委托的完成

使用这一过程有三种标准模式,区别在于:原始线程如何知道发起的线程已经完成

  • 一直等待到完成模式(wait until done):

  原始线程发起异步方法并做了一些其他处理后,原始线程中断并等待异步方法完成后再继续

  • 轮询模式(polling):

  原始线程定期检查发起的异步方法线程是否完成,如果没有则继续做其他事情

  • 回调模式(callback):

  原始线程一直执行,无需等待,当发起的线程中引用方法完成后,发起的线程就调用回调方法,调用 EndInvoke 之前处理异步方法的结果

复制代码

 1         static void Main(string[] args)
 2         {
 3             Console.WriteLine("===== 同步调用 =====");
 4             AddDel del = new AddDel(Add);
 5             int result = del.Invoke(11, 89);
 6             Console.WriteLine("计算结果:" + result);
 7             Console.WriteLine("继续削铅笔...\n");
 8             Console.ReadKey();
 9 
10             Console.WriteLine("===== 异步调用 =====");
11             IAsyncResult result_1 = del.BeginInvoke(22, 78, null, null);
12             Console.WriteLine("继续削铅笔...");
13             Console.WriteLine("计算结果:" + del.EndInvoke(result_1));
14             Console.ReadKey();
15 
16             Console.WriteLine("\n===== 异步回调 =====");
17             del.BeginInvoke(33, 67, new AsyncCallback(AddAsync), "AsyncState:OK");
18             Console.WriteLine("继续削铅笔...");
19             Console.ReadKey();
20         }
21 
22         // 委托
23         public delegate int AddDel(int a, int b);
24         // 加法计算
25         static int Add(int a, int b)
26         {
27             Console.WriteLine("开始计算:" + a + "+" + b);
28             // 模拟运行时间
29             Thread.Sleep(2000);
30             Console.WriteLine("计算完成!");
31             return a + b;
32         }
33         // 回调函数
34         static void AddAsync(IAsyncResult ar)
35         {
36             AddDel del = ((AsyncResult)ar).AsyncDelegate as AddDel;
37             Console.WriteLine("计算结果:" + del.EndInvoke(ar));
38             Console.WriteLine(ar.AsyncState);
39         }

复制代码

二、通过 Task 实现异步

Task 类通常是以异步方式执行的单个操作,更适合在后台完成的一些小任务

由于 Task 对象执行的工作通常在线程池的线程上异步执行,而不是在程序主线程上同步执行

因此可以使用 Status 属性,还可以使用 IsCancele、IsCompleted 和 IsFaulted 属性来确认任务的状态

大多数情况下,lambda 表达式用于指定的任务是执行的工作

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/104537
推荐阅读
相关标签