TPL詳解、使用


使用時注意點

 1 private async void button5_Click(object sender, EventArgs e)
 2         {
 3             /*
 4             string i1 = await F1Async();
 5             MessageBox.Show("i1=" + i1);
 6             string i2 = await F2Async();
 7             MessageBox.Show("i2=" + i2);
 8             */
 9             Task<string> task1 = F1Async();
10             Task<string> task2 = F2Async();
11             string i1 = await task1;
12             MessageBox.Show("i1=" + i1);
13             string i2 = await task2;
14             MessageBox.Show("i2=" + i2);
15         }
16 
17         static Task<string> F1Async()
18         {
19             MessageBox.Show("F1 Start");
20             return Task.Run(() => {
21                 System.Threading.Thread.Sleep(1000);
22                 MessageBox.Show("F1 Run");
23                 return "F1";
24             });
25         }
26 
27         static Task<string> F2Async()
28         {
29             MessageBox.Show("F2 Start");
30             return Task.Run(() => {
31                 System.Threading.Thread.Sleep(2000);
32                 MessageBox.Show("F2 Run");
33                 return "F2";
34             });
35         }

如上兩個異步方法,在調用時,第一種調用提示框會按步驟彈出,而第二種則混亂的彈出,但這也不難理解因為多線程本來就是分片執行不按代碼順序;

第二種寫法的await是作為一個最后的保險作用,它的意義在於如果開始就執行了ok,如果沒執行則這步該執行了

 

不能使用async修飾而要調用異步方法怎么辦?

  出現這種情況比較少,此時可以獲得Task<T>類型的返回值,獲取Task<T>.Result()方法,終止異步;

  但請注意盡量少的使用Result()方法,他會造成數據上下文的死鎖問題。

如果返回值就是一個立即可以隨手可得的值,那么就用 Task.FromResult();

 

異步方法的風格轉換

Task.Factory.FromAsync()把 IAsyncResult 轉換為 Task,這樣 APM 風格的 api 也可以用 await 來調用

 

await修飾與並發執行的順序

被await修飾的異步方法,一定會按照順序執行並結束,所以如果沒有順序要求可以不使用await修飾並發任務

eg

 1 private async void button1_Click(object sender, EventArgs e)
 2 {
 3 HttpClient hc = new HttpClient();
 4 var task1 = hc.GetStringAsync(textBox1.Text);
 5 var task2 = hc.GetStringAsync(textBox2.Text);
 6 var task3 = hc.GetStringAsync(textBox3.Text);
 7 Task.WaitAll(task1, task2, task3);
 8 label1.Text = task1.Result.Length.ToString();
 9 label2.Text = task2.Result.Length.ToString();
10 label3.Text = task3.Result.Length.ToString();
11 }
View Code

 

在接口中使用await

在接口定義是不能給接口做await修飾,然而為了增加可讀性,在方法明后添加async的特殊表示,在實現類中去添加await修飾即可

異常處理

TPL中,如果程序中出現異常,除非進行try...catch,否則有可能是感覺不到出了異常....

TPL中有時會拋出AggregateException可以同時catch住多個異常,這通常發生在並行多個任務的情況下

TPL與asp.net mvc

    1.  返回值改為Task<ActionResult>即可,如果方法標記為async,連自己創建Task都省了

1 public async Task<ActionResult> Index()
2 {
3 return View();
4 }
View Code

 

    2.  為什么asp.net中用mvc能提升系統性能?

      准確來講,不是提升性能,不會提高訪問速度,而是提升服務器的“吞吐量”,也就是可以處理的並發請求數

 

TPL常見的誤區

  1.   如果用了異步,那么就要async到底;async具有傳染性;
  2.   如果在使用異步api中摻雜了同步方法,則會打斷異步方法,有可能造成數據死鎖而且還會降低系統性能,so,不要輕易使用Wait、WaitAll
  3.   只要await、WhenAll不要task.Result、Wait、WaitAll

  

  

 


免責聲明!

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



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