拓棣呈祥 发表于 2024-5-14 17:31:19

C#异步Task

目录

[*]C#异步Task

[*]概述

[*]异步是什么?为什么需要异步?

[*]基本语法

[*]1. Task创建执行
[*]2. Task异步方法
[*]3. 取消异步执行CancellationTokenSource
[*]4.Task并行数量控制LimitedConcurrencyLevelTaskScheduler

[*]常见的应用场景
[*]总结
[*]引用


C#异步Task

概述

异步是什么?为什么需要异步?


[*]使用多线程的目的其实即使为了实现异步+并行,异步:是相对同步的,同步就是一个流程安装一个流程执行完毕,异步就是在不影响主流程的执行同时,可以执行其他流程,这也就是达到了几个逻辑并行执行的效果。
[*]异步编程要解决的问题就是许多耗时的IO可能会阻塞线程导致CPU空转降低效率,或者一个长时间的后台任务会阻塞用户界面。通过将耗时任务异步执行来使系统有更高的吞吐量,或保持界面的响应能力。
[*]同步/异步/阻塞/非阻塞/BIO/NIO/AIO 参考
https://www.cnblogs.com/lixinjie/p/a-post-about-io-clearly.html
[*]C# 中实现异步的方式有很多种,本文主要讲解常用方案Task
基本语法

1. Task创建执行

   public static void TaskCreateRun()
   {
       // 方式1: Task.Run
       Task.Run(() =>
       {
         MessageBox.Show("Task.Run");
       });

       // 方式2: Task.Factory.StartNew
       Task.Factory.StartNew(() =>
       {
         MessageBox.Show("Task.Factory.StartNew");
       });

       //方式3:new Task<返回类型>
       Task<int> t=new Task<int>(() => { MessageBox.Show("new Task"); return 1;});
       t.Start();
   }2. Task异步方法


[*]使用async关键字标记,表示该方法可以包含异步操作。
[*]通常返回Task或Task类型,其中T是返回值类型。
[*]使用await或Result关键字暂停方法执行,直到等待的异步操作完成。
[*]使用await调用异步方法,方法定义必须添加async
方法定义:通常返回Task或Task类型,其中T是返回值类型
public static async Task<string> GetStringAsync()
{
   //方式1: 使用await的方法,方法定义必须添加async
   //return await Task.Run(() =>
   //{
   //    return "Task.FromResult 返回结果";
   //});

   //方式2: 使用Task.FromResult
   return await Task.FromResult("GetStringAsync Task.FromResult 返回结果");
}

public static Task<string> GetStringAsync2()
{
   returnTask.FromResult("GetStringAsync2 Task.FromResult 返回结果");
}方法调用:使用await或result关键字暂停方法执行,获取结果。 暂停多个异步方法 WaitAll、WaitAny、WhenAll。
var r= GetStringAsync().Result;
MessageBox.Show(await GetStringAsync2());
GetStringAsync2().Wait();//同步,获取不到返回值,只适合无返回值的方法
//处理多个异步方法
Task.WaitAll(GetStringAsync2(),GetStringAsync());//同步阻塞,所有执行完成。获取不到返回值,只适合无返回值的方法。
Task.WaitAny(GetStringAsync2(),GetStringAsync());//同步阻塞,其中1个异步执行完成。获取不到返回值,只适合无返回值的方法。
//同步阻塞,获取到所有异步方法的返回值
Task.WhenAll(GetStringAsync2(), GetStringAsync()).ContinueWith(p => {
    p.Result.ToList().ForEach(t => MessageBox.Show(t));
});注意事项

[*]Task.Wait()和Task.Result 将异步转为同步,容易造成死锁。尽量少使用。
[*]调用Task.WaitAll的时候,会阻塞当前线程,直到所有的Task都完成了。而Task.WhenAll方法不会阻塞当前线程,而是直接返回了一个Task,只有在读取这个Task的Result的时候,才会引起阻塞。
3. 取消异步执行CancellationTokenSource

staticCancellationTokenSource cts = new CancellationTokenSource();
static CancellationToken token = cts.Token;
/// <summary>
/// 取消异步方法
/// </summary>
public static void TaskCanceled()
{
   Task task = Task.Run(() =>
   {
         for (int i = 0; i < 10; i++)
         {
             if (token.IsCancellationRequested)
             {
               MessageBox.Show("任务已取消");
               return;
             }

             MessageBox.Show($"正在执行操作:{i}");
             Thread.Sleep(300);
         }

         MessageBox.Show("任务完成");
   }, token);
}
//调用
    TaskCanceled();
    Thread.Sleep(3000);
    cts.Cancel();4.Task并行数量控制LimitedConcurrencyLevelTaskScheduler


[*]https://www.cnblogs.com/DiscoverPalace/archive/2015/06/10/4567222.html
[*]https://msdn.microsoft.com/zh-cn/library/system.threading.tasks.taskscheduler(v=vs.110).aspx
[*]https://github.com/chi8708/LuceneNetDemo/blob/master/JieBaLucene/LimitedConcurrencyLevelTaskScheduler.cs
常见的应用场景


[*]耗时IO或三方服务:文件下载、日志记录、消息订阅、邮件短信发送等。
[*]Web服务器: Web 服务器通常使用多线程来处理多个客户端的请求。每个请求都由一个单独的线程处理,这样可以避免单个请求阻塞其他请求。
[*]媒体播放器: 媒体播放器通常使用多线程来解码音频和视频数据。解码是一项耗时的操作,如果使用单线程进行解码,则会阻塞播放。使用多线程可以将解码和播放分开进行,从而提高播放的流畅性。
[*]游戏: 游戏通常使用多线程来渲染图形、处理玩家输入和更新游戏状态。这些任务都需要大量的 CPU 时间,使用多线程可以充分利用多核 CPU 的优势,从而提高游戏的性能。
[*]科学计算: 科学计算通常需要处理大量的数据,可以使用多线程来将计算任务分解成多个子任务,同时执行。这可以显著提高计算效率。
总结

Task是C#中一种功能强大且易于使用的异步编程工具,它可以帮助我们开发更加响应、高效和易于维护的应用程序。

[*]1、Task的创建运行可以有三种方式:new Task/Task.Factory/Task.Run
[*]2、Task的返回参数定义Task 。获取返回值:Task.Result->要阻塞主流程
[*]3、Task线程的同步实现不仅仅可以通过RunSynchronously来实现同步运行,当然还可以通过Task.Result/Task.Wait等方式来变向实现
[*]4、Task的wait/waitAll/waitAny实现阻塞等待执行结果
[*]5、Task的WhenAny、WhenAll、ContinueWith实现延续操作
[*]6、CancellationTokenSource实现异步任务取消
[*]7、异步方法之:(async/await)实现同步和异步调用等
引用


[*]博文示例代码        https://github.com/chi8708/DotNetNote/blob/master/Note.Basic/07Task.cs
[*]https://www.cnblogs.com/xiaoXuZhi/p/XYH_tsak_WhenAny1.html

来源:https://www.cnblogs.com/chi8708/p/18191278
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: C#异步Task