C#異步使用需要注意的幾個(gè)問(wèn)題
一、異步模型的基本概述
異步編程的核心是 Task 和 Task<T> 對(duì)象,這兩個(gè)對(duì)象對(duì)異步操作建模。 它們受關(guān)鍵字 async 和 await 的支持。 在大多數(shù)情況下模型十分簡(jiǎn)單:
對(duì)于 I/O 綁定代碼,當(dāng)你 await 一個(gè)操作,它將返回 async 方法中的一個(gè) Task 或 Task<T> 。
對(duì)于 CPU 綁定代碼,當(dāng)你 await 一個(gè)操作,它將在后臺(tái)線程通過(guò) Task.Run() 方法啟動(dòng)。
二、C#異步使用需要注意的幾個(gè)問(wèn)題
- 異步方法如果只是對(duì)別的方法的簡(jiǎn)單的轉(zhuǎn)發(fā)調(diào)用,沒(méi)喲復(fù)雜的邏輯(比如等待A的結(jié)果,再調(diào)用B,等待A調(diào)用的返回值拿到內(nèi)部做一些處理再返回),那么就可以去掉async關(guān)鍵字。
- 異步方法其實(shí)使用async 關(guān)鍵字clr多了一些準(zhǔn)備和 轉(zhuǎn)換的處理和線程的切換,效率反而低。
- 異步方法中想暫停一段時(shí)間,不要用thread.sleep(),因?yàn)樗麜?huì)阻塞調(diào)用線程導(dǎo)致當(dāng)前界面卡無(wú)響應(yīng),而要用await task.delay(); 例如6秒后下載一個(gè)文件
- 異步中的CancellationToken 參數(shù),用于提前終止任務(wù),比如取消任務(wù),請(qǐng)求超時(shí)
三、CancellationToken 結(jié)構(gòu)體
- None 空
- bool IsCancellationToken 是否取消
- Register(action callback)注冊(cè)取消監(jiān)聽(tīng)
- ThrowIfCancellationRequested 如果任務(wù)被取消,執(zhí)行到這句話就拋異常
- CancellationTokenSource 來(lái)創(chuàng)建 CancellationToken
- CancelAfter()超時(shí)后發(fā)出取消信號(hào)
- Cancel()發(fā)出取消信號(hào)
- CancellationToken Token
static async Task Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(5000); //超時(shí)5s后取消
await DownloadString("http://www.baidu.com", 50, cts.Token);
}
1.手動(dòng)取消
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("任務(wù)被取消");
break;
}
2.利用方法取消,拋出異常
cancellationToken.ThrowIfCancellationRequested();
3. 傳參數(shù)取消
系統(tǒng)自帶的異步方法,只需要傳參數(shù)就可取消,拋出異常
var resp= await client.GetAsync(url,cancellationToken);
4.手動(dòng)觸發(fā)事件取消任務(wù)
static async Task Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
//cts.CancelAfter(5000);
DownloadString("http://www.baidu.com", 100, cts.Token); //和超時(shí)區(qū)別在于去掉了前面的await 才生效
while (Console.ReadLine() != "q")
{
}
cts.Cancel();
Console.ReadLine();
}
.Asp.net core Mvc 控制器里面的異步方法盡量帶 CancellationToken
5.Task類方法
WhenAny任何一個(gè)Task完成,task就完成WhenAll所有任務(wù)都完成,才完成 。 不在乎Task執(zhí)行順序FromResult創(chuàng)建普通數(shù)值的Task對(duì)象
6.yield流水線返回
yield 可以流水線返回,提高性能。
C# 8.0以上支持 yield異步方法的使用
static async IAsyncenumerable<string> test()
{
yield return "a";
yield return "b";
yield return "c";
}
調(diào)用:
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.手動(dòng)取消
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("任務(wù)被取消");
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.手動(dòng)取消
//if (cancellationToken.IsCancellationRequested)
//{
// Console.WriteLine("任務(wù)被取消");
// break;
//}
//2.拋出異常
//cancellationToken.ThrowIfCancellationRequested();
}
}
}
到此這篇關(guān)于C#使用異步需要注意的幾個(gè)問(wèn)題的文章就介紹到這了,更多相關(guān)C#使用異步需要注意的問(wèn)題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c# DevExpress gridcontrol日期行的顯示格式設(shè)置
這篇文章主要介紹了c# DevExpress gridcontrol日期行的顯示格式設(shè)置,需要的朋友可以參考下2017-02-02
C#中Dictionary與List的用法區(qū)別以及聯(lián)系詳解
List和Dictionary想必是我們平常用到最多的C#容器了,他們使用起來(lái)都很簡(jiǎn)單,這篇文章主要給大家介紹了關(guān)于C#中Dictionary與List的用法區(qū)別以及聯(lián)系的相關(guān)資料,需要的朋友可以參考下2023-11-11
C#實(shí)現(xiàn)給Word每一頁(yè)設(shè)置不同圖片水印
Word中設(shè)置水印時(shí),可加載圖片設(shè)置為水印效果,但通常添加水印效果時(shí),會(huì)對(duì)所有頁(yè)面都設(shè)置成統(tǒng)一效果。本文將利用C#實(shí)現(xiàn)給Word每一頁(yè)設(shè)置不同圖片水印的效果,需要的可以參考一下2022-02-02
C#修改及重置電腦密碼DirectoryEntry實(shí)現(xiàn)方法
這篇文章主要介紹了C#修改及重置電腦密碼DirectoryEntry實(shí)現(xiàn)方法,實(shí)例分析了C#修改及重置電腦密碼的相關(guān)技巧,需要的朋友可以參考下2015-05-05
C#提取網(wǎng)頁(yè)中超鏈接link和text部分的方法
這篇文章主要介紹了C#提取網(wǎng)頁(yè)中超鏈接link和text部分的方法,涉及C#正則表達(dá)式及字符串操作相關(guān)技巧,需要的朋友可以參考下2016-02-02
C#中try...catch的使用與常見(jiàn)面試題分享
這篇文章首先給大家介紹了關(guān)于C#中try...catch的語(yǔ)法,而后又給大家分享了關(guān)于C#中try...catch最常見(jiàn)的面試題,具有一定的參考借鑒價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-02-02

