async,await和TaskCompleteSource的一些疑問

       之前看ET框架的時候,發現了一些不理解的地方。其實都是集中在async-await的用法和TaskCompleteSource的用法上的,這會兒就學習了一些。

       第一個例子:

第一個例子:

然後在Main函數中調用TaskCompleteSourceButton_OnClick方法,

TaskCompleteSourceButton_OnClick();
Console.WriteLine("等待中!!!!");
Console.ReadKey();

運行後,會發現,主線程處於阻塞的情況,後面的“等待中!!!”要等到異步任務完成後纔會輸出。

要等到異步任務完成後纔會輸出。

話說,使用async-await不是應該是異步操作的嗎?爲什麼主線程還會阻塞呢?

        再來看第二個例子:

第二個例子:

這個例子在運行的時候,就不會發生阻塞了:

就不會發生阻塞了:

這兩個例子,一個使用了TaskCompleteSource,一個沒有使用。這有關係,卻不是真正的原因,真正的原因:第一個例子的代碼,通過TaskCompleteSource類,在主線程中獲取了異步任務的運行結果,所以會造成阻塞。最簡單的測試方法就是去掉TaskCompleteSource類,在運行的時候,就會發現主線程沒有阻塞了。修改如下:

如此後,主線程就不會阻塞了。但是如果去掉while循環中的註釋的話,那麼在輸出“等待結果中!!!”後,就會直接阻塞線程。原因是一樣的,因爲這裏獲取了異步任務的返回結果,所以會發生阻塞。

        說到這裏,就要說一說TaskCompleteSource的作用了,咋一看,用不用這個類,都能獲取異步任務的記過,也都阻塞了線程,有啥區別呢?區別就在於,這個類其實是一個回調方法,任務結束後,調用這個回調可以傳遞很多任務運行的數據,包括運行結果。所以我們可以獲取該回調的來做一些事情。在貓大的給出的例子《更好的協程》中,將TaskCompleteSource對象拋出去,在一個while循環中獲取到該對象,從而解析出任務運行的結果。這樣就不會阻塞線程了,同時也可以實時獲取到異步任務的結果,符合大家對異步編程的需求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章