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

 更新时间:2021年09月10日 10:55:08   作者:天之客  
C#使用异步方法中,使用一下关键词的时候徐注意一些问题,比如async 方法需在其主体中具有 await 关键字,否则它们将永不暂停,接下来文字里将为大家举例说明

一、异步模型的基本概述

异步编程的核心是 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();
}

}

}

到此这篇关于C#使用异步需要注意的几个问题的文章就介绍到这了,更多相关C#使用异步需要注意的问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#中如何正确的使用字符串String

    C#中如何正确的使用字符串String

    这篇文章主要给大家介绍了关于在C#中如何正确的使用字符串String的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • 解析使用enumerator模式简化异步操作的详解

    解析使用enumerator模式简化异步操作的详解

    本篇文章是对使用enumerator模式简化异步操作进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • c# 通过wbemtest和WMI Code Cretor更加高效的访问WMI

    c# 通过wbemtest和WMI Code Cretor更加高效的访问WMI

    能找到这篇博客的,相信都是有操作WMI需求的了。本文将讲述如何快速验证、并集成到C#来操作WMI。
    2021-05-05
  • C#获取文件创建时间的方法

    C#获取文件创建时间的方法

    这篇文章主要介绍了C#获取文件创建时间的方法,涉及C#文件操作的技巧及CreattionTime属性的使用方法,需要的朋友可以参考下
    2015-04-04
  • 详细聊聊C#的并发机制优秀在哪

    详细聊聊C#的并发机制优秀在哪

    并发其实是一个很泛的概念,字面意思就是"同时做多件事",不过方式有所不同,下面这篇文章主要给大家介绍了关于C#并发机制的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • C#重写DataGridView

    C#重写DataGridView

    这篇文章主要为大家详细介绍了C#重写DataGridView的相关资料,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • unity实现手游虚拟摇杆

    unity实现手游虚拟摇杆

    这篇文章主要为大家详细介绍了unity实现手游虚拟摇杆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#连接Oracle数据库字符串(引入DLL)的方式

    C#连接Oracle数据库字符串(引入DLL)的方式

    这篇文章主要给大家介绍了关于C#连接Oracle数据库字符串(引入DLL)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • C#实现屏幕拷贝的方法

    C#实现屏幕拷贝的方法

    这篇文章主要介绍了C#实现屏幕拷贝的方法,实例分析了两种常用的屏幕拷贝实现技巧,需要的朋友可以参考下
    2015-06-06
  • C#基于UDP实现的P2P语音聊天工具

    C#基于UDP实现的P2P语音聊天工具

    这篇文章主要是一个应用,使用udp传送语音和文本等信息。在这个系统中没有服务端和客户端,相互通讯都是直接相互联系的,能够很好的实现效果
    2015-09-09

最新评论