C#使用異步需要注意的幾個問題


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

  

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

}

}

  

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM