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 Main1(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();
}

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

6.Task类几个方法:
1.WhenAny 任何一个Task完成,task就完成
2.WhenAll 所有任务都完成,才完成 。 不在乎Task执行顺序
3.FromResult 创建普通数值的Task对象

7.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();
}

}

}

最新文章

  1. 敏捷个人-认识自我,管理自我 v0.8.pdf 下载
  2. job_queue_processes参数讲解
  3. js 操作COOKE备忘
  4. Redis info参数总结(转)
  5. java线性表学习笔记(二)
  6. 番茄钟App(Pomodoro Tracker)
  7. codeforces 675A A. Infinite Sequence(水题)
  8. Java第一阶段总结
  9. powerMock比easyMock和Mockito更强大(转)
  10. 关于a.b和a[b]的区别
  11. C/C++ 知识点---LIB和DLL的区别与使用(网摘)
  12. Luogu P2183 巧克力
  13. C(8)
  14. MySQL多Text字段报8126错误(解决过程)
  15. uboot之ldr指令
  16. Android 异步查询框架AsyncQueryHandler的使用
  17. Struts2 xxAction-validation.xml使用
  18. day27 封装
  19. ArcGIS案例学习笔记2_2_txtexcel空间可视化和空间插值
  20. SQL存储过程例子

热门文章

  1. python3中的缺省参数和global
  2. Maven国内仓库
  3. ES6新特征
  4. 文件包含 &amp; LFI-labs靶场
  5. ASPX页面传参中文乱码处理
  6. vue传值 ---- &gt;&gt; 子传父,$emit()
  7. openstack June all-in-one 安装手册
  8. Linux线程同步之读写锁(rwlock)
  9. (转)Python爬虫--通用框架
  10. Shell-06-正则表达式