当前位置: 代码网 > it编程>编程语言>C# > C#异步Task

C#异步Task

2024年05月16日 C# 我要评论
目录C#异步Task概述异步是什么?为什么需要异步?基本语法1. Task创建执行2. Task异步方法3. 取消异步执行CancellationTokenSource4.Task并行数量控制LimitedConcurrencyLevelTaskScheduler常见的应用场景总结引用 C#异步Ta ...

c#异步task

概述

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

  • 使用多线程的目的其实即使为了实现异步+并行,异步:是相对同步的,同步就是一个流程安装一个流程执行完毕,异步就是在不影响主流程的执行同时,可以执行其他流程,这也就是达到了几个逻辑并行执行的效果。
  • 异步编程要解决的问题就是许多耗时的io可能会阻塞线程导致cpu空转降低效率,或者一个长时间的后台任务会阻塞用户界面。通过将耗时任务异步执行来使系统有更高的吞吐量,或保持界面的响应能力。
  • 同步/异步/阻塞/非阻塞/bio/nio/aio 参考
  • 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()
 {
     return  task.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

static  cancellationtokensource 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

常见的应用场景

  • 耗时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)实现同步和异步调用等

引用

  1. 博文示例代码 https://github.com/chi8708/dotnetnote/blob/master/note.basic/07task.cs

  2. https://www.cnblogs.com/xiaoxuzhi/p/xyh_tsak_whenany1.html

(0)

相关文章:

  • WPF实现html中的table控件的示例代码

    前言相信很多做wpf开发的小伙伴都遇到过表格类的需求,虽然现有的grid控件也能实现,但是使用起来的体验感并不好,比如要实现一个excel中的表格效果,估计你能想到的第一个方法就是…

    2024年05月15日 编程语言
  • C# wpf嵌入winform控件的示例详解

    前言wpf的强大界面能力,再加上winform的性能以及灵活性,那基本上什么界面都能够做的很好。比如视频渲染用winform,功能按键用wpf,就能达到性能和界面效果和完美结合。w…

    2024年05月15日 编程语言
  • 详解C# wpf如何嵌入hwnd窗口

    详解C# wpf如何嵌入hwnd窗口

    前言wpf是direct ui,窗口中只有一个hwnd句柄,大部分控件都是直接在上面绘制的。当我们需要使用不同的渲染方式进行绘制时,就会和控件绘制产生冲突。比如... [阅读全文]
  • C#实现实时监控文件夹变化

    C#实现实时监控文件夹变化

    在开发各种应用程序时,我们经常需要对文件系统中的文件或文件夹进行实时监测,以便在文件内容改变、文件被创建或删除时能够及时做出反应。在 c# 中,system.i... [阅读全文]
  • c# 执行动态编译的方法实例详解

    c# 执行动态编译的方法实例详解

    c# 执行动态编译的方法在c#中执行动态编译的一种方法是使用 csharpcodeprovider 类。这类可以用来编译和执行c#代码,下面是一个简单的例子:u... [阅读全文]
  • C#结合Minio实现文件上传存储与更新

    C#结合Minio实现文件上传存储与更新

    前言minio是一个开源的对象存储服务器,专门设计用于在大规模数据存储环境中运行。它兼容amazon s3 api,因此可以作为一个替代方案用于存储和检索数据,... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com