C#异步使用需要注意的几个问题

作者:天之客 时间:2023-03-05 04:33:08 

一、异步模型的基本概述

异步编程的核心是 Task Task<T> 对象,这两个对象对异步操作建模。 它们受关键字 async await 的支持。 在大多数情况下模型十分简单:

对于 I/O 绑定代码,当你 await 一个操作,它将返回 async 方法中的一个 Task Task<T>
对于 CPU 绑定代码,当你 await 一个操作,它将在后台线程通过 Task.Run() 方法启动。

二、C#异步使用需要注意的几个问题

  1. 异步方法如果只是对别的方法的简单的转发调用,没哟复杂的逻辑(比如等待A的结果,再调用B,等待A调用的返回值拿到内部做一些处理再返回),那么就可以去掉async关键字。

  2. 异步方法其实使用async 关键字clr多了一些准备和 转换的处理和线程的切换,效率反而低。

  3. 异步方法中想暂停一段时间,不要用thread.sleep(),因为他会阻塞调用线程导致当前界面卡无响应,而要用await task.delay(); 例如6秒后下载一个文件

  4. 异步中的CancellationToken 参数,用于提前终止任务,比如取消任务,请求超时

三、CancellationToken 结构体

  • None 空

  • bool IsCancellationToken 是否取消

  • Register(action callback)注册取消监听

  • ThrowIfCancellationRequested 如果任务被取消,执行到这句话就抛异常

  • CancellationTokenSource 来创建 CancellationToken

  • CancelAfter()超时后发出取消信号

  • Cancel()发出取消信号

  • CancellationToken Token


static async Task Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(5000); //超时5s后取消
await DownloadString("http://www.baidu.com", 50, cts.Token);
}

1.手动取消


if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("任务被取消");
break;
}

2.利用方法取消,抛出异常


cancellationToken.ThrowIfCancellationRequested();

3. 传参数取消

系统自带的异步方法,只需要传参数就可取消,抛出异常


var resp= await client.GetAsync(url,cancellationToken);

4.手动触发事件取消任务


static async Task Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
//cts.CancelAfter(5000);
DownloadString("http://www.baidu.com", 100, cts.Token); //和超时区别在于去掉了前面的await 才生效
while (Console.ReadLine() != "q")
{

}
cts.Cancel();
Console.ReadLine();
}

.Asp.net core Mvc 控制器里面的异步方法尽量带 CancellationToken

5.Task类方法

  • WhenAny 任何一个Task完成,task就完成

  • WhenAll 所有任务都完成,才完成 。 不在乎Task执行顺序

  • FromResult 创建普通数值的Task对象

6.yield流水线返回

yield 可以流水线返回,提高性能。

C# 8.0以上支持 yield异步方法的使用


static async IAsyncenumerable<string> test()
{
yield return "a";
yield return "b";
yield return "c";
}

调用:


await foreach(var o in test())
{
Console.WriteLine(o);
}


public static async Task DownloadString(string url,int num,CancellationToken cancellationToken)
{
try
{
using (var client = new HttpClient())
{
for (int i = 0; i < num; i++)
{

string html = await client.GetStringAsync(url);
Console.WriteLine($"{DateTime.Now}:{html}");
//1.手动取消
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("任务被取消");
break;
}

//2.抛出异常
//cancellationToken.ThrowIfCancellationRequested();
}

}

}
catch (Exception)
{

throw;
}

}

public static async Task Download2String(string url, int num, CancellationToken cancellationToken)
{
using (var client = new HttpClient())
{
for (int i = 0; i < num; i++)
{

var resp= await client.GetAsync(url,cancellationToken);

string html =await resp.Content.ReadAsStringAsync();
Console.WriteLine($"{DateTime.Now}:{html}");
//1.手动取消
//if (cancellationToken.IsCancellationRequested)
//{
// Console.WriteLine("任务被取消");
// break;
//}

//2.抛出异常
//cancellationToken.ThrowIfCancellationRequested();
}

}

}

来源:https://www.tuicool.com/articles/2muY73I

标签:C#,异步
0
投稿

猜你喜欢

  • Java输入输出流的使用详细介绍

    2023-08-01 22:21:22
  • 详解JAVA流程控制语句

    2023-11-05 02:27:09
  • 关于Mybatis的@param注解及多个传参

    2021-09-10 21:17:21
  • 详解Java泛型及其应用

    2023-09-21 22:38:32
  • Java中instanceof关键字的用法总结

    2022-12-11 15:52:27
  • 零基础写Java知乎爬虫之先拿百度首页练练手

    2022-11-14 09:07:05
  • idea项目的左侧目录没了如何设置

    2022-03-21 15:45:43
  • SpringCloud @FeignClient参数的用法解析

    2022-11-25 06:31:37
  • 分享C#中几个可用的类

    2023-08-10 10:47:17
  • c#多种加解密示例(md5加密解密)

    2022-08-26 07:17:10
  • linux的shell命令检测某个java程序是否执行

    2021-07-27 14:32:20
  • Flutter Widget开发之Focus组件图文详解

    2023-06-21 03:47:41
  • SpringCloud之@FeignClient()注解的使用方式

    2022-05-16 04:22:40
  • Java数据结构之优先级队列(堆)图文详解

    2021-06-25 13:47:58
  • Springboot 整合RabbitMq(用心看完这一篇就够了)

    2023-11-23 05:27:17
  • MyBatis学习教程(五)-实现关联表查询方法详解

    2021-06-23 21:04:04
  • Android仿新浪微博分页管理界面(3)

    2023-08-04 19:14:02
  • java Matcher匹配头尾截取替换字符串的案例

    2023-01-30 11:44:48
  • WPF自定义控件的实现

    2021-07-06 02:34:11
  • C#检查foreach判读是否为null的方法

    2021-10-28 01:37:24
  • asp之家 软件编程 m.aspxhome.com